labthings_fastapi.thing_description

Thing Description module

This module supports the generation of Thing Descriptions. Currently, the top level function lives in labthings_fastapi.thing.Thing.thing_description(), but most of the supporting code is in this submodule.

A Pydantic model implementing the Thing Description is in .model, and this is used to generate our TDs - it helps make sure any TD errors get caught when they are generated in Python, which makes them much easier to debug.

We also use the JSONSchema provided by W3C to validate the TDs we generate, in .validation, as a double-check that we are standards-compliant.

Submodules

Package Contents

Functions

is_a_reference

Return True if a JSONSchema dict is a reference

look_up_reference

Look up a reference in a JSONSchema

is_an_object

Determine whether a JSON schema dict is an object

convert_object

Convert an object from JSONSchema to Thing Description

convert_anyof

Convert the anyof key to oneof

convert_prefixitems

Convert the prefixitems key to items

convert_additionalproperties

Move additionalProperties into properties, or remove it

check_recursion

Check the recursion count is less than the limit

jsonschema_to_dataschema

remove references and change field formats

type_to_dataschema

Convert a Python type to a Thing Description DataSchema

Data

JSONSchema

API

labthings_fastapi.thing_description.JSONSchema

None

labthings_fastapi.thing_description.is_a_reference(d: labthings_fastapi.thing_description.JSONSchema) bool

Return True if a JSONSchema dict is a reference

JSON Schema references are one-element dictionaries with a single key, $ref. pydantic sometimes breaks this rule and so I don’t check that it’s a single key.

labthings_fastapi.thing_description.look_up_reference(reference: str, d: labthings_fastapi.thing_description.JSONSchema) labthings_fastapi.thing_description.JSONSchema

Look up a reference in a JSONSchema

This first asserts the reference is local (i.e. starts with # so it’s relative to the current file), then looks up each path component in turn.

labthings_fastapi.thing_description.is_an_object(d: labthings_fastapi.thing_description.JSONSchema) bool

Determine whether a JSON schema dict is an object

labthings_fastapi.thing_description.convert_object(d: labthings_fastapi.thing_description.JSONSchema) labthings_fastapi.thing_description.JSONSchema

Convert an object from JSONSchema to Thing Description

labthings_fastapi.thing_description.convert_anyof(d: labthings_fastapi.thing_description.JSONSchema) labthings_fastapi.thing_description.JSONSchema

Convert the anyof key to oneof

JSONSchema makes a distinction between “anyof” and “oneof”, where the former means “any of these fields can be present” and the latter means “exactly one of these fields must be present”. Thing Description does not have this distinction, so we convert anyof to oneof.

labthings_fastapi.thing_description.convert_prefixitems(d: labthings_fastapi.thing_description.JSONSchema) labthings_fastapi.thing_description.JSONSchema

Convert the prefixitems key to items

JSONSchema 2019 (as used by thing description) used items with a list of values in the same way that JSONSchema now uses prefixitems.

JSONSchema 2020 uses items to mean the same as additionalItems in JSONSchema 2019 - but Thing Description doesn’t support the additionalItems keyword. This will result in us overwriting additional items, and we raise a ValueError if that happens.

This behaviour may be relaxed in the future.

labthings_fastapi.thing_description.convert_additionalproperties(d: labthings_fastapi.thing_description.JSONSchema) labthings_fastapi.thing_description.JSONSchema

Move additionalProperties into properties, or remove it

labthings_fastapi.thing_description.check_recursion(depth: int, limit: int)

Check the recursion count is less than the limit

labthings_fastapi.thing_description.jsonschema_to_dataschema(d: labthings_fastapi.thing_description.JSONSchema, root_schema: Optional[labthings_fastapi.thing_description.JSONSchema] = None, recursion_depth: int = 0, recursion_limit: int = 99) labthings_fastapi.thing_description.JSONSchema

remove references and change field formats

JSONSchema allows schemas to be replaced with {"$ref": "#/path/to/schema"}. Thing Description does not allow this. dereference_jsonschema_dict takes a dict representation of a JSON Schema document, and replaces all the references with the appropriate chunk of the file.

JSONSchema can represent Union types using the anyOf keyword, which is called oneOf by Thing Description. It’s possible to achieve the same thing in the specific case of array elements, by setting items to a list of DataSchema objects. This function does not yet do that conversion.

This generates a copy of the document, to avoid messing up pydantic’s cache.

labthings_fastapi.thing_description.type_to_dataschema(t: type, **kwargs) labthings_fastapi.thing_description.model.DataSchema

Convert a Python type to a Thing Description DataSchema

This makes use of pydantic’s schema_of function to create a json schema, then applies some fixes to make a DataSchema as per the Thing Description (because Thing Description is almost but not quite compatible with JSONSchema).

Additional keyword arguments are added to the DataSchema, and will override the fields generated from the type that is passed in. Typically you’ll want to use this for the title field.