labthings_fastapi.utilities =========================== .. py:module:: labthings_fastapi.utilities .. autoapi-nested-parse:: Utility functions used by LabThings-FastAPI. Submodules ---------- .. toctree:: :maxdepth: 1 /autoapi/labthings_fastapi/utilities/introspection/index Classes ------- .. autoapisummary:: labthings_fastapi.utilities.RootModelWrapper Functions --------- .. autoapisummary:: labthings_fastapi.utilities.class_attributes labthings_fastapi.utilities.attributes labthings_fastapi.utilities.model_to_dict Package Contents ---------------- .. py:function:: 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 `.attributes` on ``obj.__class__``. :param obj: The instance, usually a `~lt.Thing` instance. :yield: tuples of ``(name, value)`` giving each attribute of the class. .. py:function:: attributes(cls: Any) -> Iterable[tuple[str, Any]] List all the attributes of an object not starting with `__`. :param 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. .. py:class:: RootModelWrapper Bases: :py:obj:`pydantic.RootModel`\ [\ :py:obj:`WrappedT`\ ], :py:obj:`Generic`\ [\ :py:obj:`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.BaseModel` subclasses, and to unwrap them again. .. py:method:: wrap_type(model: type, constraints: collections.abc.Mapping[str, Any] | None = None, name: str | None = None) -> type[pydantic.BaseModel] :classmethod: Ensure a type is a subclass of BaseModel. If a `pydantic.BaseModel` subclass is passed to this function, we will pass it through unchanged. Otherwise, we wrap the type in a `pydantic.RootModel`. In the future, we may explicitly check that the argument is a type and not a model instance. :param model: A Python type or `pydantic` model. :param constraints: is passed as keyword arguments to `pydantic.Field` to add validation constraints to the property. :param name: the name to use for the dynamically created model. :return: A `pydantic` model, wrapping Python types in a ``RootModel`` if needed. :raises UnsupportedConstraintError: if constraints are provided for an unsuitable type, for example `allow_inf_nan` for an `int` property, or any constraints for a `BaseModel` subclass. :raises UnserialisableTypeError: if the type being wrapped is not able to be serialised by `pydantic`\ . :raises RuntimeError: if other errors prevent Pydantic from creating a schema for the generated model. .. py:method:: unwrap(value: pydantic.BaseModel | None) -> Any :classmethod: If the supplied value is a `RootModelWrapper`, unwrap it. :param value: a model instance. :return: the root value, if ``value`` is a `RootModelWrapper`\ , or ``value`` if not. .. py:function:: model_to_dict(model: Optional[pydantic.BaseModel]) -> 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 of `None` (converted to an empty dictionary) and `pydantic.RootModel` (checked to see if they correspond to empty input). If `pydantic.RootModel` with non-empty input is allowed, this function will need to be updated to handle them. :param model: A Pydantic model (usually the input of an action). :return: A dictionary with string keys, which are the fields of the model. This should be suitable for using as ``**kwargs`` to an action. :raise ValueError: if we are given a root model that isn't empty.