JSON Schema

structtype provides a few utilities for generating JSON Schema specifications from structtype-compatible types and constraints.

  • json_schema(): a function that generates a complete JSON Schema as a Python dict.

  • json_schema_dump(): a convenience wrapper that returns the schema as JSON bytes.

  • json_schema_components(): generates schemas for multiple types at once, returning per-type schemas and shared component definitions. Usable in other frameworks.

The generated schemas are compatible with JSON Schema 2020-12 and OpenAPI 3.1.

Example

from structtype import json_schema, json_schema_dump
from structtype import Struct, Field
from typing import Annotated


class Dimensions(Struct):
    length: Annotated[float, Field(gt=0)]
    width: Annotated[float, Field(gt=0)]
    height: Annotated[float, Field(gt=0)]


class Product(Struct):
    id: int
    name: str
    tags: set[str] = set()
    dimensions: Dimensions | None = None


# Generate a schema as a Python dict
result = json_schema(Product)

# Or get it directly as JSON bytes
json_bytes = json_schema_dump(Product)
{
  "$ref": "#/$defs/Product",
  "$defs": {
    "Product": {
      "title": "Product",
      "type": "object",
      "properties": {
        "id": {"type": "integer"},
        "name": {"type": "string"},
        "tags": {
          "type": "array",
          "items": {"type": "string"},
          "uniqueItems": true,
          "default": []
        },
        "dimensions": {
          "anyOf": [
            {"$ref": "#/$defs/Dimensions"},
            {"type": "null"}
          ],
          "default": null
        }
      },
      "required": ["id", "name"]
    },
    "Dimensions": {
      "title": "Dimensions",
      "type": "object",
      "properties": {
        "length": {"type": "number", "exclusiveMinimum": 0},
        "width": {"type": "number", "exclusiveMinimum": 0},
        "height": {"type": "number", "exclusiveMinimum": 0}
      },
      "required": ["length", "width", "height"]
    }
  }
}

Schema Components

If you need to generate schemas for multiple related types, use json_schema_components(). This is more efficient than calling json_schema() in a loop, and returns separate per-type schemas together with shared component definitions:

>>> from structtype import json_schema_components

>>> schemas, components = json_schema_components([Dimensions, Product])

>>> len(schemas)
2

>>> # schemas[0] corresponds to the Dimensions type
... schemas[0]
{'$ref': '#/$defs/Dimensions', ...}

>>> # schemas[1] corresponds to the Product type
... schemas[1]
{'$ref': '#/$defs/Product', ...}

>>> # components is a dict mapping type names to their sub-schemas
... list(components.keys())
['Dimensions', 'Product']

>>> # For a single type, json_schema_dump is a convenience shortcut
... from structtype import json_schema_dump
... json_schema_dump(Product)
b'...'

Both functions accept the following keyword arguments:

  • schema_hook: A callable that can modify the generated schema for any type. It receives the original type and should return a dict of schema properties to merge.

  • ref_template: A string template for $ref paths. Defaults to "#/$defs/{name}".

Customizing the Schema

You can enrich the generated JSON Schema using several Field parameters. These appear in the schema output as additional metadata.

title and description

>>> from typing import Annotated
>>> from structtype import Struct, Field

>>> class Product(Struct):
...     name: Annotated[str, Field(
...         title="Product Name",
...         description="The display name of the product"
...     )]

examples

Provide example values that will appear in the generated schema:

>>> from typing import Annotated
>>> from structtype import Struct, Field

>>> class Product(Struct):
...     name: Annotated[str, Field(examples=["Widget", "Gadget"])]

json_schema_extra

Add arbitrary extra properties to the generated schema for a field:

>>> from typing import Annotated
>>> from structtype import Struct, Field

>>> class Product(Struct):
...     sku: Annotated[str, Field(
...         json_schema_extra={"deprecated": True}
...     )]