labthings_fastapi.utilities
Utility functions used by LabThings-FastAPI.
Submodules
Classes
A RootModel subclass for automatically-wrapped types. |
Functions
|
List all the attributes of an object's class. |
|
List all the attributes of an object not starting with |
|
Convert a pydantic model to a dictionary, non-recursively. |
Package Contents
- labthings_fastapi.utilities.class_attributes(obj: Any) Iterable[tuple[str, Any]]
List all the attributes of an object’s class.
This function gets all class attributes, including inherited ones. It is used to obtain the various descriptors used to represent properties and actions. It calls
attributesonobj.__class__.- Parameters:
obj – The instance, usually a
Thinginstance.- Yield:
tuples of
(name, value)giving each attribute of the class.
- labthings_fastapi.utilities.attributes(cls: Any) Iterable[tuple[str, Any]]
List all the attributes of an object not starting with
__.- Parameters:
cls – The object whose attributes we are listing. This may be a class, because classes are objects too.
- Yield:
tuples of
(name, value)giving each attribute and its value.
- class labthings_fastapi.utilities.RootModelWrapper
Bases:
pydantic.RootModel[WrappedT],Generic[WrappedT]A RootModel subclass for automatically-wrapped types.
There are several places where LabThings needs a model, but may only have a plain Python type. This subclass indicates to LabThings that a type has been automatically wrapped, and will need to be unwrapped in order for the value to have the correct type.
It also provides methods to automatically wrap types if they are not already
pydantic.BaseModelsubclasses, and to unwrap them again.- classmethod wrap_type(model: type, constraints: collections.abc.Mapping[str, Any] | None = None, name: str | None = None) type[pydantic.BaseModel]
Ensure a type is a subclass of BaseModel.
If a
pydantic.BaseModelsubclass is passed to this function, we will pass it through unchanged. Otherwise, we wrap the type in apydantic.RootModel. In the future, we may explicitly check that the argument is a type and not a model instance.- Parameters:
model – A Python type or
pydanticmodel.constraints – is passed as keyword arguments to
pydantic.Fieldto add validation constraints to the property.name – the name to use for the dynamically created model.
- Returns:
A
pydanticmodel, wrapping Python types in aRootModelif needed.- Raises:
UnsupportedConstraintError – if constraints are provided for an unsuitable type, for example
allow_inf_nanfor anintproperty, or any constraints for aBaseModelsubclass.UnserialisableTypeError – if the type being wrapped is not able to be serialised by
pydantic.RuntimeError – if other errors prevent Pydantic from creating a schema for the generated model.
- classmethod unwrap(value: pydantic.BaseModel | None) Any
If the supplied value is a
RootModelWrapper, unwrap it.- Parameters:
value – a model instance.
- Returns:
the root value, if
valueis aRootModelWrapper, orvalueif not.
- labthings_fastapi.utilities.model_to_dict(model: pydantic.BaseModel | None) Dict[str, Any]
Convert a pydantic model to a dictionary, non-recursively.
We convert only the top level model, i.e. we do not recurse into submodels. This is important to avoid serialising Blob objects in action inputs. This function returns
dict(model), with exceptions for the case ofNone(converted to an empty dictionary) andpydantic.RootModel(checked to see if they correspond to empty input).If
pydantic.RootModelwith non-empty input is allowed, this function will need to be updated to handle them.- Parameters:
model – A Pydantic model (usually the input of an action).
- Returns:
A dictionary with string keys, which are the fields of the model. This should be suitable for using as
**kwargsto an action.- Raises:
ValueError – if we are given a root model that isn’t empty.