labthings_fastapi.utilities.introspection

A collection of utility functions to analyse types and metadata

Many parts of LabThings require us to use type annotations to generate schemas/validation/documentation. This is done using pydantic in keeping with the underlying FastAPI library.

This module collects together some utility functions that help with a few key tasks, in particular creating pydantic models from functions by analysing their signatures.

Module Contents

Classes

EmptyObject

StrictEmptyObject

EmptyInput

StrictEmptyInput

Functions

input_model_from_signature

Create a pydantic model for a function’s signature.

function_dependencies

Determine whether a function’s arguments require dependencies

fastapi_dependency_params

Find the arguments of a function that are FastAPI dependencies

return_type

Determine the return type of a function.

get_docstring

Return the docstring of an object

get_summary

Return the first line of the dosctring of an object

API

class labthings_fastapi.utilities.introspection.EmptyObject

Bases: pydantic.BaseModel

model_config

‘ConfigDict(…)’

class labthings_fastapi.utilities.introspection.StrictEmptyObject

Bases: labthings_fastapi.utilities.introspection.EmptyObject

model_config

‘ConfigDict(…)’

class labthings_fastapi.utilities.introspection.EmptyInput

Bases: pydantic.RootModel

root: Optional[labthings_fastapi.utilities.introspection.EmptyObject]

None

class labthings_fastapi.utilities.introspection.StrictEmptyInput

Bases: labthings_fastapi.utilities.introspection.EmptyInput

root: Optional[labthings_fastapi.utilities.introspection.StrictEmptyObject]

None

labthings_fastapi.utilities.introspection.input_model_from_signature(func: Callable, remove_first_positional_arg: bool = False, ignore: Optional[Sequence[str]] = None) type[pydantic.BaseModel]

Create a pydantic model for a function’s signature.

This is deliberately quite a lot more basic than pydantic.decorator.ValidatedFunction because it is designed to handle JSON input. That means that we don’t want positional arguments, unless there’s exactly one (in which case we have a single value, not an object, and this may or may not be supported).

This will fail for position-only arguments, though that may change in the future.

Parameters:
  • remove_first_positional_arg – Remove the first argument from the model (this is appropriate for methods, as the first argument, self, is baked in when it’s called, but is present in the signature).

  • ignore – Ignore arguments that have the specified name. This is useful for e.g. dependencies that are injected by LabThings.

Returns:

A pydantic model class describing the input parameters

TODO: deal with (or exclude) functions with a single positional parameter

labthings_fastapi.utilities.introspection.function_dependencies(func: Callable, dependency_types: Sequence[Type]) Dict[str, tuple[type, type]]

Determine whether a function’s arguments require dependencies

The return value maps argument names to a tuple of (type, full_type) where full_type is the annotation without simplification, i.e. it will include the contents of any Annotated objects.

labthings_fastapi.utilities.introspection.fastapi_dependency_params(func: Callable) Sequence[inspect.Parameter]

Find the arguments of a function that are FastAPI dependencies

This allows us to “pass through” the full power of the FastAPI dependency injection system to thing actions.

labthings_fastapi.utilities.introspection.return_type(func: Callable) Type

Determine the return type of a function.

labthings_fastapi.utilities.introspection.get_docstring(obj: Any, remove_summary=False) Optional[str]

Return the docstring of an object

If remove_newlines is True (default), newlines are removed from the string. If remove_summary is True (not default), and the docstring’s second line is blank, the first two lines are removed. If the docstring follows the convention of a one-line summary, a blank line, and a description, this will get just the description.

If remove_newlines is False, the docstring is processed by inspect.cleandoc() to remove whitespace from the start of each line.

Parameters:
  • obj – Any Python object

  • remove_newlines – bool (Default value = True)

  • remove_summary – bool (Default value = False)

Returns:

str: Object docstring

labthings_fastapi.utilities.introspection.get_summary(obj: Any) Optional[str]

Return the first line of the dosctring of an object

Parameters:

obj – Any Python object

Returns:

str: First line of object docstring