Module xmodel.remote.options
Expand source code
from xmodel.common.utils import SetUnsetValues
from typing import TypeVar, Generic, TYPE_CHECKING, Dict, Type
from xmodel.remote.response_state import ErrorHandler
from .model import RemoteModel
from xinject import Dependency
if TYPE_CHECKING:
from .api import RemoteApi
T = TypeVar("T")
# todo: I think I want to have an ability to more directly use this, and simplify this a bit...
# I look at our I did the `Field` object, that was a better way in part for what this needs....
# See RestClient._get_objects for a place where I need to temporary alter options
# to disable `auto_get_child_objects`.
# I don't have time to figure it right now, but hope I will soon....
class ApiOptions(Generic[T], SetUnsetValues):
cache_by_id: bool = False
""" If value is:
- `True`: Overrides what model class was constructed with and cache's by id.
- `False`: Overrides what model class was constructed with and does not cache by id.
"""
error_handler: ErrorHandler[T] = None
"""
The system first consults the objects 'obj.api.response_state.error_handler'
(`xmodel.remote.response_state.ResponseState.error_handler`).
If that's `None` it next checks the ApiOptions at `ObjType.api.options` for error_handler.
If it's not set there, then checks the ObjType.api.options in the each parent XContext.
Finally, we check the options passed in when ObjType class was defined.
If this is still None, then the standard error handler will happen.
The first error handler that returns True
Check `base.client.RestClient` for other error handling options I have now, and will add in
the future. Thinking about adding something there to 'catch' all the errors that happen
from any BaseModel/Type.
"""
auto_get_child_objects: bool = False
""" When retrieving objects it will retrieve all of the child objects at the same time.
It can do this in-bulk, if retrieved parent-objects in bulk at the same time
(ie: fetches a full page and then auto-bulk-fetches child objects associated with
parent objects in that page that was fetched).
"""
def __init__(self, cache_by_id: bool = None):
if cache_by_id is not None:
self.cache_by_id = cache_by_id
def __repr__(self):
return (
'ApiOptions('
f'cache_by_id={self.cache_by_id!r}, error_handler={self.error_handler}'
')'
)
class ApiOptionsGroup(Dependency):
""" Keeps track of a collection of current options for specific Api's/Model types.
"""
_api_structure_to_options_map: Dict[Type[RemoteModel], ApiOptions]
def __init__(self):
self._api_structure_to_options_map = {}
def get(self, *, api: 'RemoteApi', create_if_needed=True) -> ApiOptions:
options = self._api_structure_to_options_map.get(api.model_type)
if options:
return options
if not create_if_needed:
return None
options = ApiOptions()
self._api_structure_to_options_map[api.model_type] = options
return options
Classes
class ApiOptions (cache_by_id: bool = None)
-
Abstract base class for generic types.
A generic type is typically declared by inheriting from this class parameterized with one or more type variables. For example, a generic mapping type might be defined as::
class Mapping(Generic[KT, VT]): def getitem(self, key: KT) -> VT: … # Etc.
This class can then be used as follows::
def lookup_name(mapping: Mapping[KT, VT], key: KT, default: VT) -> VT: try: return mapping[key] except KeyError: return default
Expand source code
class ApiOptions(Generic[T], SetUnsetValues): cache_by_id: bool = False """ If value is: - `True`: Overrides what model class was constructed with and cache's by id. - `False`: Overrides what model class was constructed with and does not cache by id. """ error_handler: ErrorHandler[T] = None """ The system first consults the objects 'obj.api.response_state.error_handler' (`xmodel.remote.response_state.ResponseState.error_handler`). If that's `None` it next checks the ApiOptions at `ObjType.api.options` for error_handler. If it's not set there, then checks the ObjType.api.options in the each parent XContext. Finally, we check the options passed in when ObjType class was defined. If this is still None, then the standard error handler will happen. The first error handler that returns True Check `base.client.RestClient` for other error handling options I have now, and will add in the future. Thinking about adding something there to 'catch' all the errors that happen from any BaseModel/Type. """ auto_get_child_objects: bool = False """ When retrieving objects it will retrieve all of the child objects at the same time. It can do this in-bulk, if retrieved parent-objects in bulk at the same time (ie: fetches a full page and then auto-bulk-fetches child objects associated with parent objects in that page that was fetched). """ def __init__(self, cache_by_id: bool = None): if cache_by_id is not None: self.cache_by_id = cache_by_id def __repr__(self): return ( 'ApiOptions(' f'cache_by_id={self.cache_by_id!r}, error_handler={self.error_handler}' ')' )
Ancestors
- typing.Generic
- SetUnsetValues
Class variables
var auto_get_child_objects : bool
-
When retrieving objects it will retrieve all of the child objects at the same time. It can do this in-bulk, if retrieved parent-objects in bulk at the same time (ie: fetches a full page and then auto-bulk-fetches child objects associated with parent objects in that page that was fetched).
var cache_by_id : bool
-
If value is:
True
: Overrides what model class was constructed with and cache's by id.False
: Overrides what model class was constructed with and does not cache by id.
var error_handler : ErrorHandler[~T]
-
The system first consults the objects 'obj.api.response_state.error_handler' (
ResponseState.error_handler
).If that's
None
it next checks the ApiOptions atObjType.api.options
for error_handler. If it's not set there, then checks the ObjType.api.options in the each parent XContext. Finally, we check the options passed in when ObjType class was defined.If this is still None, then the standard error handler will happen.
The first error handler that returns True
Check
base.client.RestClient
for other error handling options I have now, and will add in the future. Thinking about adding something there to 'catch' all the errors that happen from any BaseModel/Type.
Methods
def set_unset_values(self, parent: Optional[ForwardRef('SetUnsetValues')])
-
Inherited from:
SetUnsetValues
.set_unset_values
Deprecated since version: Update (2021-03-26): I want to eventually remove all use of this.
Look at
xmodel..fields.Field
class for better example of how …
class ApiOptionsGroup
-
Keeps track of a collection of current options for specific Api's/Model types.
Expand source code
class ApiOptionsGroup(Dependency): """ Keeps track of a collection of current options for specific Api's/Model types. """ _api_structure_to_options_map: Dict[Type[RemoteModel], ApiOptions] def __init__(self): self._api_structure_to_options_map = {} def get(self, *, api: 'RemoteApi', create_if_needed=True) -> ApiOptions: options = self._api_structure_to_options_map.get(api.model_type) if options: return options if not create_if_needed: return None options = ApiOptions() self._api_structure_to_options_map[api.model_type] = options return options
Ancestors
Static methods
def __init_subclass__(thread_sharable=Default, attributes_to_skip_while_copying: Optional[Iterable[str]] = Default, **kwargs)
-
Inherited from:
Dependency
.__init_subclass__
Args
thread_sharable
- If
False
: While a dependency is lazily auto-created, we will ensure we do it per-thread, and not make it visible …
def grab() ‑> ~T
-
Inherited from:
Dependency
.grab
Gets a potentially shared dependency from the current
udpend.context.XContext
… def proxy() ‑> ~R
-
Inherited from:
Dependency
.proxy
Returns a proxy-object, that when and attribute is asked for, it will proxy it to the current object of
cls
… def proxy_attribute(attribute_name: str) ‑> Any
-
Inherited from:
Dependency
.proxy_attribute
Returns a proxy-object, that when and attribute is asked for, it will proxy it to the current attribute value on the current object of
cls
…
Instance variables
var obj : Dependency
-
Inherited from:
Dependency
.obj
class property/attribute that will return the current dependency for the subclass it's asked on by calling
Dependency.grab
, passing no extra …
Methods
def __call__(self, func)
-
Inherited from:
Dependency
.__call__
This makes Resource subclasses have an ability to be used as function decorators by default unless this method is overriden to provide some other …
def __copy__(self)
-
Inherited from:
Dependency
.__copy__
Basic shallow copy protection (I am wondering if I should just remove this default copy code) …
def get(self, *, api: RemoteApi, create_if_needed=True) ‑> ApiOptions
-
Expand source code
def get(self, *, api: 'RemoteApi', create_if_needed=True) -> ApiOptions: options = self._api_structure_to_options_map.get(api.model_type) if options: return options if not create_if_needed: return None options = ApiOptions() self._api_structure_to_options_map[api.model_type] = options return options