API Docs

Structs

class structtype.Struct

A base class for defining efficient serializable objects.

Fields are defined using type annotations. Fields may optionally have default values, which result in keyword parameters to the constructor.

Structs automatically define __init__, __eq__, __repr__, and __copy__ methods. Additional methods can be defined on the class as needed. Note that __init__/__new__ cannot be overridden, but other methods can. A tuple of the field names is available on the class via the __struct_fields__ attribute if needed.

Additional class options can be enabled by passing keywords to the class definition (see example below). These configuration options may also be inspected at runtime through the __struct_config__ attribute.

Configuration:
  • frozen (bool, default False) – Whether instances of this type are pseudo-immutable. If true, attribute assignment is disabled and a corresponding __hash__ is defined.

  • order (bool, default False) – If True, __lt__, __le__`, __gt__, and __ge__ methods will be generated for this type.

  • eq (bool, default True) – If True (the default), an __eq__ method will be generated for this type. Set to False to compare based on instance identity alone.

  • kw_only (bool, default False) – If True, all fields will be treated as keyword-only arguments in the generated __init__ method. Default is False.

  • omit_defaults (bool, default False) – Whether fields should be omitted from encoding if the corresponding value is the default for that field. Enabling this may reduce message size, and often also improve encoding & decoding performance.

  • forbid_unknown_fields (bool, default False) – If True, an error is raised if an unknown field is encountered while decoding structs of this type. If False (the default), no error is raised and the unknown field is skipped.

  • tag (str, int, bool, callable, or None, default None) – Used along with tag_field for configuring tagged union support. If either are non-None, then the struct is considered “tagged”. In this case, an extra field (the tag_field) and value (the tag) are added to the encoded message, which can be used to differentiate message types during decoding.

    Set tag=True to enable the default tagged configuration (tag_field is "type", tag is the class name). Alternatively, you can provide a string (or less commonly int) value directly to be used as the tag (e.g. tag="my-tag-value").``tag`` can also be passed a callable that takes the class qualname and returns a valid tag value (e.g. tag=str.lower). See the docs for more information.

  • tag_field (str or None, default None) – The field name to use for tagged union support. If tag is non-None, then this defaults to "type". See the tag docs above for more information.

  • rename (str, mapping, callable, or None, default None) – Controls renaming the field names used when encoding/decoding the struct. May be one of "lower", "upper", "camel", "pascal", or "kebab" to rename in lowercase, UPPERCASE, camelCase, PascalCase, or kebab-case respectively. May also be a mapping from field names to the renamed names (missing fields are not renamed). Alternatively, may be a callable that takes the field name and returns a new name or None to not rename that field. Default is None for no field renaming.

  • repr_omit_defaults (bool, default False) – Whether fields should be omitted from the generated repr if the corresponding value is the default for that field.

  • array_like (bool, default False) – If True, this struct type will be treated as an array-like type during encoding/decoding, rather than a dict-like type (the default). This may improve performance, at the cost of a more inscrutable message encoding.

  • gc (bool, default True) – Whether garbage collection is enabled for this type. Disabling this may help reduce GC pressure, but will prevent reference cycles composed of only gc=False from being collected. It is the user’s responsibility to ensure that reference cycles don’t occur when setting gc=False.

  • weakref (bool, default False) – Whether instances of this type support weak references. Defaults to False.

  • dict (bool, default False) – Whether instances of this type will include a __dict__. Setting this to True will allow adding additional undeclared attributes to a struct instance, which may be useful for holding private runtime state. Defaults to False.

  • cache_hash (bool, default False) – If enabled, the hash of a frozen struct instance will be computed at most once, and then cached on the instance for further reuse. For expensive hash values this can improve performance at the cost of a small amount of memory usage.

Examples

Here we define a new Struct type for describing a dog. It has three fields; two required and one optional.

>>> class Dog(Struct):
...     name: str
...     breed: str
...     is_good_boy: bool = True
...
>>> Dog('snickers', breed='corgi')
Dog(name='snickers', breed='corgi', is_good_boy=True)

Additional struct options can be set as part of the class definition. Here we define a new Struct type for a frozen Point object.

>>> class Point(Struct, frozen=True):
...     x: float
...     y: float
...
>>> {Point(1.5, 2.0): 1}  # frozen structs are hashable
{Point(x=1.5, y=2.0): 1}
struct_dump()

Convert this struct to built-in Python types

struct_dump_json()

Serialize this struct to JSON bytes

struct_force_setattr()

Force set an attribute on a frozen struct

struct_to_dict()

Convert this struct to a dict

struct_to_tuple()

Convert this struct to a tuple

classmethod struct_validate()

Convert built-in types to this struct type

classmethod struct_validate_json()

Deserialize JSON bytes to this struct type

class structtype.StructMeta(name, bases, namespace, /, *, **struct_config)

The metaclass for creating Struct types. See its documentation for the available configuration options when subclassing.

StructMeta can be subclassed, and may be combined with abc.ABCMeta to define abstract base Structs. Other metaclass combinations are not supported; they may work by accident but are not considered part of the public API.

Examples

Here we define a metaclass that modifies the default configuration and use it to create a new Struct base class.

>>> from structtype import Struct, StructMeta
>>> class KwOnlyStructMeta(StructMeta):
...     def __new__(mcls, name, bases, namespace, **struct_config):
...         struct_config.setdefault("kw_only", True)
...         return super().__new__(mcls, name, bases, namespace, **struct_config)
...
>>> class KwOnlyStruct(Struct, metaclass=KwOnlyStructMeta): ...

Any subclass of KwOnlyStruct will have kw_only set to True by default.

>>> class Example(KwOnlyStruct):
...     a: str =
...     b: int
...
>>> Example(b=123)
Example(a='', b=123)
structtype.fields(type_or_instance)
structtype.json_schema(type, *, schema_hook=None, ref_template='#/$defs/{name}')

Generate a JSON Schema for a given type.

Any schemas for (potentially) shared components are extracted and stored in a top-level "$defs" field.

If you want to generate schemas for multiple types, or to have more control over the generated schema you may want to use json_schema_components instead.

Parameters:
  • type (type) – The type to generate the schema for.

  • schema_hook (callable, optional) – An optional callback to use for generating JSON schemas of custom types. Will be called with the custom type, and should return a dict representation of the JSON schema for that type.

  • ref_template (str, optional) – A template to use when generating "$ref" fields. This template is formatted with the type name as template.format(name=name). This can be useful if you intend to store the components mapping somewhere other than a top-level "$defs" field. For example, you might use ref_template="#/components/{name}" if generating an OpenAPI schema.

Returns:

schema (dict) – The generated JSON Schema.

structtype.json_schema_dump(type, *, schema_hook=None, ref_template='#/$defs/{name}')

Generate a JSON Schema for the given type, returned as JSON bytes.

This is a convenience wrapper around json_schema() that encodes the result to JSON.

Parameters:
  • type (type) – The type to generate the schema for.

  • schema_hook (callable, optional) – An optional callback to use for generating JSON schemas of custom types.

  • ref_template (str, optional) – A template to use when generating "$ref" fields.

structtype.json_schema_components(types, *, schema_hook=None, ref_template='#/$defs/{name}')

Generate JSON Schemas for one or more types.

Any schemas for (potentially) shared components are extracted and returned in a separate components dict.

Parameters:
  • types (Iterable[type]) – An iterable of one or more types to generate schemas for.

  • schema_hook (callable, optional) – An optional callback to use for generating JSON schemas of custom types. Will be called with the custom type, and should return a dict representation of the JSON schema for that type.

  • ref_template (str, optional) – A template to use when generating "$ref" fields. This template is formatted with the type name as template.format(name=name). This can be useful if you intend to store the components mapping somewhere other than a top-level "$defs" field. For example, you might use ref_template="#/components/{name}" if generating an OpenAPI schema.

Returns:

  • schemas (tuple[dict]) – A tuple of JSON Schemas, one for each type in types.

  • components (dict) – A mapping of name to schema for any shared components used by schemas.

See also

schema

class structtype.FieldInfo(name, encode_name, type, default=UNSET, default_factory=UNSET)

A record describing a field in a struct.

class structtype.StructConfig

Configuration settings for a given Struct type.

This object is accessible through the __struct_config__ field on a struct type or instance. It exposes the following attributes, matching the Struct configuration parameters of the same name. See the Struct docstring for details.

Configuration:
  • frozen (bool)

  • eq (bool)

  • order (bool)

  • array_like (bool)

  • gc (bool)

  • repr_omit_defaults (bool)

  • omit_defaults (bool)

  • forbid_unknown_fields (bool)

  • weakref (bool)

  • dict (bool)

  • cache_hash (bool)

  • tag_field (str | None)

  • tag (str | int | None)

structtype.NODEFAULT

A singleton indicating no default value is configured.

Field

class structtype.Field

Configuration for a Struct field.

Parameters:
  • default (Any, optional) – A default value to use for this field.

  • default_factory (callable, optional) – A zero-argument function called to generate a new default value per-instance, rather than using a constant value as in default.

  • alias (str, optional) – An alternative name to use when encoding/decoding this field. If present, this will override any struct-level configuration using the rename option for this field.

  • gt (int or float, optional) – The annotated value must be greater than gt.

  • ge (int or float, optional) – The annotated value must be greater than or equal to ge.

  • lt (int or float, optional) – The annotated value must be less than lt.

  • le (int or float, optional) – The annotated value must be less than or equal to le.

  • multiple_of (int or float, optional) – The annotated value must be a multiple of multiple_of.

  • pattern (str, optional) – A regex pattern that the annotated value must match against. Note that the pattern is treated as unanchored, meaning the re.search method is used when matching.

  • min_length (int, optional) – The annotated value must have a length >= min_length.

  • max_length (int, optional) – The annotated value must have a length <= max_length.

  • tz (bool, optional) – Configures the timezone-requirements for annotated datetime/ time types. Set to True to require timezone-aware values, or False to require timezone-naive values. The default is None, which accepts either.

  • title (str, optional) – The title to use for the annotated value when generating a json-schema.

  • description (str, optional) – The description to use for the annotated value when generating a json-schema.

  • examples (list, optional) – A list of examples to use when generating a json-schema.

  • json_schema_extra (dict, optional) – A dict of extra fields to set when generating a json-schema. This dict is recursively merged with the generated schema, with json_schema_extra overriding any conflicting autogenerated fields.

Examples

Here we use Field to add constraints on two different types. The first defines a new type alias NonNegativeInt, which is an integer that must be >= 0. This type alias can be reused in multiple locations. The second uses Field inline in a struct definition to restrict the name string field to a maximum length of 32 characters.

>>> from typing import Annotated
>>> from structtype import Struct, Field
>>> NonNegativeInt = Annotated[int, Field(ge=0)]
>>> class User(Struct):
...     name: Annotated[str, Field(max_length=32)]
...     age: NonNegativeInt
...
>>> User.struct_validate_json(b'{"name": "alice", "age": 25}')
User(name='alice', age=25)
alias

An alternative name to use when encoding/decoding this field

default

The default value, or NODEFAULT if no default

default_factory

The default_factory, or NODEFAULT if no default

Raw

class structtype.Raw

A buffer containing an encoded message.

Raw objects have two common uses:

  • During decoding. Fields annotated with the Raw type won’t be decoded immediately, but will instead return a Raw object with a view into the original message where that field is encoded. This is useful for decoding fields whose type may only be inferred after decoding other fields.

  • During encoding. Raw objects wrap pre-encoded messages. These can be added as components of larger messages without having to pay the cost of decoding and re-encoding them.

Parameters:

msg (bytes, bytearray, memoryview, or str, optional) – A buffer containing an encoded message. One of bytes, bytearray, memoryview, str, or any object that implements the buffer protocol. If not present, defaults to an empty buffer.

copy()

Copy a Raw object.

If the raw message is backed by a memoryview into a larger buffer (as happens during decoding), the message is copied and the reference to the larger buffer released. This may be useful to reduce memory usage if a Raw object created during decoding will be kept in memory for a while rather than immediately decoded and dropped.

Unset

structtype.UNSET

A singleton indicating a field value is unset.

This may be useful for working with message schemas where an unset field in an object needs to be treated differently than one containing an explicit None value. In this case, you may use UNSET as the default value, rather than None when defining object schemas. This feature is supported for any structtype.Struct, dataclasses or attrs types.

Examples

>>> from structtype import Struct, UnsetType, UNSET
>>> class Example(Struct):
...     x: int
...     y: int | None | UnsetType = UNSET

During encoding, any field containing UNSET is omitted from the message.

>>> Example(1).struct_dump_json()
b'{"x":1}'
>>> Example(1, 2).struct_dump_json()
b'{"x":1,"y":2}'

During decoding, if a field isn’t explicitly set in the message, the default value of UNSET will be set instead. This lets downstream consumers determine whether a field was left unset, or explicitly set to None

>>> Example.struct_validate_json(b'{"x": 1}')  # unset
Example(x=1, y=UNSET)
>>> Example.struct_validate_json(b'{"x": 1, "y": null}')  # explicit null
Example(x=1, y=None)
>>> Example.struct_validate_json(b'{"x": 1, "y": 2}')  # explicit value
Example(x=1, y=2)
class structtype.UnsetType

The type of UNSET.

See also

UNSET

StructAdapter

class structtype.StructAdapter(type)

Adapter for validating and serializing types without subclassing Struct.

Useful when you want to validate or serialize plain Python types (e.g. list[int]) without defining a full Struct subclass.

>>> from structtype import StructAdapter
>>> adapter = StructAdapter(list[int])
>>> adapter.struct_validate_json(b"[1, 2, 3]")
[1, 2, 3]
struct_dump(obj)

Convert a validated object to built-in Python types (dict, list, etc.).

struct_dump_json(obj, *, enc_hook=None, decimal_format=None, uuid_format=None, order=None)

Encode a validated object to JSON bytes.

Parameters:
  • obj (Any) – A value to encode. Must match the adapter’s type.

  • enc_hook (callable, optional) – A callback for customizing encoding of specific types.

  • decimal_format (str or callable, optional) – Controls how Decimal values are encoded.

  • uuid_format (str, optional) – Controls how UUID values are encoded.

  • order (str, optional) – Determines key ordering in JSON objects.

struct_validate(obj, *, strict=True, dec_hook=None, from_attributes=False)

Validate a Python object against the adapter’s type.

Parameters:
  • obj (Any) – A Python object to validate and convert.

  • strict (bool, optional) – If True (default), unmatched fields cause an error.

  • dec_hook (callable, optional) – A callback for customizing decoding of specific types.

  • from_attributes (bool, optional) – If True, accept objects with attributes instead of dict keys.

struct_validate_json(buf, *, strict=True, dec_hook=None)

Validate JSON bytes and decode into the adapter’s type.

Parameters:
  • buf (str or bytes) – The JSON message to decode.

  • strict (bool, optional) – If True (default), unmatched fields cause an error.

  • dec_hook (callable, optional) – A callback for customizing decoding of specific types.

StrAdapter

class structtype.StrAdapter(typ)

Create a str subclass wrapper for validating a type during structtype serialization.

Wraps a type that has a single-argument string constructor (e.g. HttpUrl, EmailStr, IPv4Address) into a str subclass. The wrapped value is stored as a string but validated by calling typ(value) on construction. During structtype validation and serialization, the wrapper is treated as a native str.

>>> from structtype import StrAdapter, Struct
>>> from ipaddress import IPv4Address
>>>
>>> class Config(Struct):
...     ip: StrAdapter(IPv4Address)

Exceptions

exception structtype.EncodeError

Bases: ValueError

An error occurred while encoding an object

exception structtype.DecodeError

Bases: ValueError

An error occurred while decoding an object

exception structtype.ValidationError

Bases: ValueError

The message didn’t match the expected schema