labthings_fastapi.server.config_model

Pydantic models to enable server configuration to be loaded from file.

The models in this module allow ThingConfig dataclasses to be constructed from dictionaries or JSON files. They also describe the full server configuration with ServerConfigModel. These models are used by the labthings_fastapi.server.cli module to start servers based on configuration files or strings.

Attributes

ThingImportString

RESERVED_THING_NAMES

ThingName

ThingsConfig

Exceptions

ThingImportFailure

Failed to import Thing. Raise with import traceback.

Classes

ThingConfig

The information needed to add a Thing to a ThingServer.

ThingServerConfig

The configuration parameters for a ThingServer.

Functions

contain_import_errors(→ Any)

Prevent errors during import from causing odd validation errors.

check_reserved_thing_names(→ str)

Validate a Thing name by checking it's not in a list of banned names.

normalise_things_config(...)

Ensure every Thing is defined by a ThingConfig object.

Module Contents

exception labthings_fastapi.server.config_model.ThingImportFailure

Bases: BaseException

Failed to import Thing. Raise with import traceback.

Initialize self. See help(type(self)) for accurate signature.

labthings_fastapi.server.config_model.contain_import_errors(value: Any, handler: pydantic.ValidatorFunctionWrapHandler) Any

Prevent errors during import from causing odd validation errors.

This is used to wrap the pydantic ImportString validator, and ensures that any module that won’t import shows up with a single clear error.

Parameters:
  • value – The value being validated.

  • handler – The validator handler.

Returns:

The validated value.

Raises:
  • ThingImportFailure – if an import error occurs, with the stack trace from retrying the import.

  • Exception – In the unlikely event that the import error cannot be reproduced

labthings_fastapi.server.config_model.ThingImportString
class labthings_fastapi.server.config_model.ThingConfig(/, **data: Any)

Bases: pydantic.BaseModel

The information needed to add a Thing to a ThingServer.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

cls: ThingImportString = None
args: collections.abc.Sequence[Any] = None
kwargs: collections.abc.Mapping[str, Any] = None
thing_slots: collections.abc.Mapping[str, str | collections.abc.Iterable[str] | None] = None
labthings_fastapi.server.config_model.RESERVED_THING_NAMES = ('things', 'cls')
labthings_fastapi.server.config_model.check_reserved_thing_names(name: str) str

Validate a Thing name by checking it’s not in a list of banned names.

Parameters:

name – the name to check.

Returns:

the name, if valid.

Raises:

ValueError – if the name is not valid.

labthings_fastapi.server.config_model.ThingName
type labthings_fastapi.server.config_model.ThingsConfig = Mapping[ThingName, ThingConfig | ThingImportString]
class labthings_fastapi.server.config_model.ThingServerConfig(/, **data: Any)

Bases: pydantic.BaseModel

The configuration parameters for a ThingServer.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

things: ThingsConfig = None
classmethod check_things(things: ThingsConfig) ThingsConfig

Check that the thing configurations can be normalised.

It’s possible to specify the things as a mapping from names to classes. We use pydantic.ImportString as the type of the classes: this takes a string, and imports the corresponding Python object. When loading config from JSON, this does the right thing - but when loading from Python objects it will accept any Python object.

This validator runs normalise_thing_config to check each value is either a valid ThingConfig or a type or a mapping. If it’s a mapping, we will attempt to make a ThingConfig from it. If it’s a type we will create a ThingConfig using that type as the class. We don’t check for Thing subclasses in this module to avoid a dependency loop.

Parameters:

things – The validated value of the field.

Returns:

A copy of the input, with all values converted to ThingConfig instances.

property thing_configs: collections.abc.Mapping[ThingName, ThingConfig]

A copy of the things field where every value is a ThingConfig.

The field validator on things already ensures it returns a mapping, but it’s not typed strictly, to allow Things to be specified with just a class.

This property returns the list of ThingConfig objects, and is typed strictly.

settings_folder: str | None = None
api_prefix: str = None
enable_global_lock: bool = None
application_config: dict[str, Any] | None = None
labthings_fastapi.server.config_model.normalise_things_config(things: ThingsConfig) collections.abc.Mapping[ThingName, ThingConfig]

Ensure every Thing is defined by a ThingConfig object.

Things may be specified either using a ThingConfig object, or just a bare Thing subclass, if the other parameters are not needed. To simplify code that uses the configuration, this function wraps bare classes in a ThingConfig so the values are uniformly typed.

Parameters:

things – A mapping of names to Things, either classes or ThingConfig objects.

Returns:

A mapping of names to ThingConfig objects.

Raises:

ValueError – if a Python object is passed that’s neither a type nor a dict.