Laid a ton of groundwork and got the first AdapterManager function working
This commit is contained in:
@@ -1,11 +1,24 @@
|
||||
import abc
|
||||
from typing import Any, Dict, List, Tuple
|
||||
from dataclasses import dataclass
|
||||
from typing import (
|
||||
Any,
|
||||
Dict,
|
||||
Iterable,
|
||||
List,
|
||||
Optional,
|
||||
Type,
|
||||
Tuple,
|
||||
Union,
|
||||
)
|
||||
from pathlib import Path
|
||||
|
||||
from .api_objects import (Playlist, PlaylistDetails)
|
||||
from .api_objects import (
|
||||
Playlist,
|
||||
PlaylistDetails,
|
||||
)
|
||||
|
||||
|
||||
class AdapterCacheMiss(Exception):
|
||||
class CacheMissError(Exception):
|
||||
"""
|
||||
This exception should be thrown by caching adapters when the request
|
||||
data is not available or is invalid.
|
||||
@@ -13,6 +26,44 @@ class AdapterCacheMiss(Exception):
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class ConfigParamDescriptor:
|
||||
"""
|
||||
Describes a parameter that can be used to configure an adapter. The
|
||||
:class:`description`, :class:`required` and :class:`default:` should be
|
||||
self-evident as to what they do.
|
||||
|
||||
The :class:`type` must be one of the following:
|
||||
|
||||
* The literal type ``str``: corresponds to a freeform text entry field in
|
||||
the UI.
|
||||
* The literal type ``bool``: corresponds to a checkbox in the UI.
|
||||
* The literal type ``int``: corresponds to a numeric input in the UI.
|
||||
* The literal string ``"password"``: corresponds to a password entry field
|
||||
in the UI.
|
||||
* The literal string ``"option"``: corresponds to dropdown in the UI.
|
||||
|
||||
The :class:`numeric_bounds` parameter only has an effect if the
|
||||
:class:`type` is `int`. It specifies the min and max values that the UI
|
||||
control can have.
|
||||
|
||||
The :class:`numeric_step` parameter only has an effect if the :class:`type`
|
||||
is `int`. It specifies the step that will be taken using the "+" and "-"
|
||||
buttons on the UI control (if supported).
|
||||
|
||||
The :class:`options` parameter only has an effect if the :class:`type` is
|
||||
``"option"``. It specifies the list of options that will be available in
|
||||
the dropdown in the UI.
|
||||
"""
|
||||
type: Union[Type, str]
|
||||
description: str
|
||||
required: bool = True
|
||||
default: Any = None
|
||||
numeric_bounds: Optional[Tuple[int, int]] = None
|
||||
numeric_step: Optional[int] = None
|
||||
options: Optional[Iterable[str]] = None
|
||||
|
||||
|
||||
class Adapter(abc.ABC):
|
||||
"""
|
||||
Defines the interface for a Sublime Music Adapter.
|
||||
@@ -27,25 +78,41 @@ class Adapter(abc.ABC):
|
||||
# =========================================================================
|
||||
@staticmethod
|
||||
@abc.abstractmethod
|
||||
def get_config_parameters() -> List[Tuple[str, str]]: # TODO fix
|
||||
def get_config_parameters() -> Dict[str, ConfigParamDescriptor]:
|
||||
"""
|
||||
Specifies the settings which can be configured for the adapter.
|
||||
|
||||
Tuples of (config_key, parameter_config)
|
||||
The config_key gets used in the config dict in __init__
|
||||
|
||||
TODO
|
||||
:returns: An ordered dictionary where the keys are the name of the
|
||||
configuration paramter and the values are the
|
||||
:class:`ConfigParamDescriptor` object corresponding to that
|
||||
configuration parameter. The order of the keys in the dictionary
|
||||
correspond to the order that the configuration parameters will be
|
||||
shown in the UI.
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
@abc.abstractmethod
|
||||
def verify_configuration(config: Dict[str, Any]) -> Dict[str, str]:
|
||||
def verify_configuration(
|
||||
config: Dict[str, Any]) -> Dict[str, Optional[str]]:
|
||||
"""
|
||||
Specifies a function for verifying whether or not a config is valid.
|
||||
Specifies a function for verifying whether or not the config is valid.
|
||||
|
||||
Return a dict of field: ('verification error' OR None)
|
||||
:param config: The adapter configuration. The keys of are the
|
||||
configuration parameter names as defined by the return value of the
|
||||
:class:`get_config_parameters` function. The values are the actual
|
||||
value of the configuration parameter.
|
||||
|
||||
TODO
|
||||
It is guaranteed that all configuration parameters that are marked
|
||||
as required will have a value in ``config``.
|
||||
|
||||
:returns: A dictionary containing varification errors. The keys of the
|
||||
returned dictionary should be the same as the passed in via the
|
||||
``config`` parameter. The values should be strings describing why
|
||||
the corresponding value in the ``config`` dictionary is invalid.
|
||||
|
||||
Not all keys need be returned (for example, if there's no error for
|
||||
a given configuration parameter), and returning `None` indicates no
|
||||
error.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
@@ -55,8 +122,19 @@ class Adapter(abc.ABC):
|
||||
:class:`Adapter` and should be used to do whatever setup is
|
||||
required for the adapter.
|
||||
|
||||
:param config: TODO
|
||||
:param data_directory: the directory where the adapter can store data
|
||||
:param config: The adapter configuration. The keys of are the
|
||||
configuration parameter names as defined by the return value of the
|
||||
:class:`get_config_parameters` function. The values are the actual
|
||||
value of the configuration parameter.
|
||||
:param data_directory: the directory where the adapter can store data.
|
||||
This directory is guaranteed to exist.
|
||||
"""
|
||||
|
||||
def shutdown(self):
|
||||
"""
|
||||
This function is called when the app is being closed or the server is
|
||||
changing. This should be used to clean up anything that is necessary
|
||||
such as writing a cache to disk, disconnecting from a server, etc.
|
||||
"""
|
||||
|
||||
# Usage Properties
|
||||
@@ -111,8 +189,8 @@ class Adapter(abc.ABC):
|
||||
# =========================================================================
|
||||
def get_playlists(self) -> List[Playlist]:
|
||||
"""
|
||||
Gets a list of all of the :class:`Playlist` objects known to the
|
||||
adapter.
|
||||
Gets a list of all of the :class:`sublime.adapter.api_objects.Playlist`
|
||||
objects known to the adapter.
|
||||
"""
|
||||
raise self._check_can_error('get_playlists')
|
||||
|
||||
@@ -161,17 +239,32 @@ class CachingAdapter(Adapter):
|
||||
:class:`CachingAdapter` and should be used to do whatever setup is
|
||||
required for the adapter.
|
||||
|
||||
:param config: TODO
|
||||
:param data_directory: the directory where the adapter can store data
|
||||
:param is_cache: whether or not the adapter is being used as a cache
|
||||
:param config: The adapter configuration. The keys of are the
|
||||
configuration parameter names as defined by the return value of the
|
||||
:class:`get_config_parameters` function. The values are the actual
|
||||
value of the configuration parameter.
|
||||
:param data_directory: the directory where the adapter can store data.
|
||||
This directory is guaranteed to exist.
|
||||
:param is_cache: whether or not the adapter is being used as a cache.
|
||||
"""
|
||||
|
||||
# Data Ingestion Methods
|
||||
# =========================================================================
|
||||
@abc.abstractmethod
|
||||
def ingest_new_data(self): # TODO: actually ingest data
|
||||
def ingest_new_data(
|
||||
self,
|
||||
function_name: str,
|
||||
params: Tuple[Any, ...],
|
||||
data: Any,
|
||||
):
|
||||
"""
|
||||
This function will be called after the fallback, ground-truth adapter
|
||||
returns new data. This normally will happen if this adapter has a cache
|
||||
miss or if the UI forces retrieval from the ground-truth adapter.
|
||||
|
||||
:param function_name: the name of the function that was called on the
|
||||
ground truth adapter.
|
||||
:param params: the parameters that were passed to the function on the
|
||||
ground truth adapter.
|
||||
:param data: the data that was returned by the ground truth adapter.
|
||||
"""
|
||||
|
Reference in New Issue
Block a user