labthings_fastapi.types.numpy

Basic support for numpy arrays in Pydantic models.

We define a type alias NDArray which is a numpy array, annotated to allow pydantic to convert it to and from JSON (as an array-of-arrays).

This should allow numpy arrays to be used without explicit conversion:

from labthings_fastapi.types.ndarray import NDArray


def double(arr: NDArray) -> NDArray:
    return arr * 2  # arr is a numpy.ndarray

The implementation is not super elegant: it isn’t recursive so has only been defined for up to 6d arrays. Specifying the dimensionality might be a nice touch, but is left for the future.

Complex numbers are currently not supported, again this is left for the future.

Attributes

Number

NestedListOfNumbers

NDArray

An annotated type that enables pydantic to handle numpy.ndarray.

Classes

NestedListOfNumbersModel

A RootModel describing a list-of-lists up to 7 deep.

DenumpifyingDict

A pydantic model for a dictionary that converts arrays to lists.

Functions

np_to_listoflists(→ NestedListOfNumbers)

Convert a numpy array to a list of lists.

listoflists_to_np(→ numpy.ndarray)

Convert a list of lists to a numpy array (or pass-through ndarrays).

denumpify(→ Any)

Convert any numpy array in a dict into a list.

denumpify_serialiser(→ Any)

Denumpify mappings before serialization.

Module Contents

type labthings_fastapi.types.numpy.Number = int | float
type labthings_fastapi.types.numpy.NestedListOfNumbers = Number | List[Number] | List[List[Number]] | List[List[List[Number]]] | List[List[List[List[Number]]]] | List[List[List[List[List[Number]]]]] | List[List[List[List[List[List[Number]]]]]] | List[List[List[List[List[List[List]]]]]]
class labthings_fastapi.types.numpy.NestedListOfNumbersModel(/, root=PydanticUndefined, **data)

Bases: pydantic.RootModel

A RootModel describing a list-of-lists up to 7 deep.

This is used to generate a JSONSchema description of a numpy.ndarray serialised to a list. It is used in the annotated NDArray type.

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.

root: NestedListOfNumbers
labthings_fastapi.types.numpy.np_to_listoflists(arr: numpy.ndarray) NestedListOfNumbers

Convert a numpy array to a list of lists.

NB this will not be quick! Large arrays will be much better serialised by dumping to base64 encoding or similar.

Parameters:

arr – a numpy.ndarray.

Returns:

a nested list of numbers.

labthings_fastapi.types.numpy.listoflists_to_np(lol: NestedListOfNumbers | numpy.ndarray) numpy.ndarray

Convert a list of lists to a numpy array (or pass-through ndarrays).

Parameters:

lol – a nested list of numbers.

Returns:

a numpy.ndarray.

type labthings_fastapi.types.numpy.NDArray = Annotated[np.ndarray, PlainValidator(listoflists_to_np), PlainSerializer(np_to_listoflists, when_used='json-unless-none', return_type=NestedListOfNumbers), WithJsonSchema(NestedListOfNumbersModel.model_json_schema(), mode='validation')]

An annotated type that enables pydantic to handle numpy.ndarray.

NDArray “validates” numpy.ndarray objects by converting a nested list of numbers into an numpy.ndarray using numpy.asarray. Similarly, it calls numpy.ndarray.tolist to convert the array back into a serialisable structure.

The JSON Schema representation is a nested list up to 7 deep, which is cumbersome but correct.

In the future it would be good to replace this type with several types of different, specified dimensionality. That would make for much less horrible Thing Description representations, as well as giving useful information about the datatype returned.

labthings_fastapi.types.numpy.denumpify(v: Any) Any

Convert any numpy array in a dict into a list.

Parameters:

v – the data to convert, may be a mapping, sequence, or other.

Returns:

the input datastructure, with all numpy.ndarray objects converted to lists.

labthings_fastapi.types.numpy.denumpify_serialiser(v: Any, nxt: pydantic.SerializerFunctionWrapHandler) Any

Denumpify mappings before serialization.

This is intended for use as a “wrap serialiser” in pydantic, and will remove numpy.ndarray objects from a data structure using denumpify. This should allow dicts containing numpy.ndarray objects to be serialised to JSON.

Parameters:
  • v – input data, of any type.

  • nxt – the next serialiser, see pydantic docs.

Returns:

the data structure with numpy.ndarray objects removed.

class labthings_fastapi.types.numpy.DenumpifyingDict(/, root=PydanticUndefined, **data)

Bases: pydantic.RootModel

A pydantic model for a dictionary that converts arrays to lists.

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.

root: Annotated[collections.abc.Mapping, WrapSerializer(denumpify_serialiser)]
model_config

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].