Skip to main content

JSON Schema Draft v7 (http://json-schema.org/) formatting with marshmallow

Project description

marshmallow-jsonschema: JSON Schema formatting with marshmallow

Build Status Code style: black

marshmallow-jsonschema translates marshmallow schemas into JSON Schema Draft v7 compliant documents.

Why would I want my schema translated to JSON?

A few common reasons:

  • Render a marshmallow schema as a form in another runtime (web browser, mobile, native desktop) where you can't import Python.
  • Validate request/response bodies in an API gateway or contract-test layer that consumes JSON Schema directly.
  • Publish your schema as documentation alongside an OpenAPI spec.

Installation

Requires Python 3.9+ and marshmallow 3.13 or later (works on both marshmallow 3 and marshmallow 4).

pip install marshmallow-jsonschema

For older environments:

  • marshmallow 2 → marshmallow-jsonschema<0.11
  • Python 3.6–3.8 or marshmallow 3.11–3.12 → marshmallow-jsonschema<0.14
  • A marshmallow-4-broken intermediate state → marshmallow-jsonschema<0.14 (with marshmallow<4)

Client tools that render forms from JSON Schema

Examples

Simple example

from marshmallow import Schema, fields
from marshmallow_jsonschema import JSONSchema

class UserSchema(Schema):
    username = fields.String()
    age = fields.Integer()
    birthday = fields.Date()

JSONSchema().dump(UserSchema())

Yields:

{
    "$schema": "http://json-schema.org/draft-07/schema#",
    "$ref": "#/definitions/UserSchema",
    "definitions": {
        "UserSchema": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
                "age": {"title": "age", "type": "integer"},
                "birthday": {"title": "birthday", "type": "string", "format": "date"},
                "username": {"title": "username", "type": "string"}
            }
        }
    }
}

Nested example

Nested schemas land in definitions and are referenced via $ref:

from marshmallow import Schema, fields
from marshmallow_jsonschema import JSONSchema

class AddressSchema(Schema):
    street = fields.String()
    city = fields.String()

class UserSchema(Schema):
    name = fields.String()
    address = fields.Nested(AddressSchema)

JSONSchema().dump(UserSchema())

Yields:

{
    "$schema": "http://json-schema.org/draft-07/schema#",
    "$ref": "#/definitions/UserSchema",
    "definitions": {
        "AddressSchema": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
                "city": {"title": "city", "type": "string"},
                "street": {"title": "street", "type": "string"}
            }
        },
        "UserSchema": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
                "address": {"type": "object", "$ref": "#/definitions/AddressSchema"},
                "name": {"title": "name", "type": "string"}
            }
        }
    }
}

fields.Nested("Self") and fields.Nested(lambda: SomeSchema()) are both supported for recursive references.

Flask + JSON Schema form rendering

A complete runnable Flask example lives at example/example.py. It exposes a marshmallow schema as JSON Schema and renders it as a form using json-editor — pure JS, no build pipeline, drop in via CDN:

pip install -r example/requirements.txt
python example/example.py
# open http://127.0.0.1:5000/

For a richer React-based alternative, see ReactJsonSchemaFormJSONSchema below.

Validators

Marshmallow's standard validators translate automatically into JSON Schema constraints when the field is dumped:

Validator JSON Schema output
validate.Length(min=, max=) minLength / maxLength for strings, minItems / maxItems for lists & nested
validate.Range(min=, max=, min_inclusive=, max_inclusive=) minimum / maximum (or exclusiveMinimum / exclusiveMaximum)
validate.OneOf(choices, labels=) enum (and the non-standard enumNames for compatibility with react-jsonschema-form)
validate.Equal(value) enum: [value]
validate.Regexp(pattern) pattern
validate.ContainsOnly(choices, labels=) items.anyOf: [{const}, ...] + uniqueItems: true
from marshmallow import Schema, fields, validate
from marshmallow_jsonschema import JSONSchema

class UserSchema(Schema):
    age = fields.Integer(validate=validate.Range(min=0, max=150))
    name = fields.String(validate=validate.Length(min=1, max=100))
    role = fields.String(validate=validate.OneOf(["admin", "user"]))

For a custom validator that's a subclass of one of the above, set _jsonschema_base_validator_class = validate.<Base> on it so the translation still fires.

Enums

marshmallow.fields.Enum (added in marshmallow 3.18) is supported out of the box and emits the enum-member names. The third-party marshmallow-enum EnumField is also supported when installed; native Enum is preferred when both are present.

Advanced usage

Schema-level title and description

Setting title or description on a schema's inner Meta class emits them at the corresponding definition entry:

class UserSchema(Schema):
    class Meta:
        title = "User"
        description = "A user account record."

    name = fields.String()

Customizing the definitions path

By default nested schemas live under #/definitions/<Name>. Pass definitions_path to use a different single-segment key:

JSONSchema(definitions_path="schemas").dump(MySchema())
# {"$ref": "#/schemas/MySchema", "schemas": {...}, ...}

Multi-segment paths (e.g. "components/schemas") are rejected because they would produce a flat dict key with a slash in it rather than the nested structure consumers expect — wrap the output yourself if you need that shape.

Custom field types

Add a _jsonschema_type_mapping method to your field so we know how to serialize it. Field-level metadata={...} and dump_default values are then merged in automatically, so a single mapping method gets you the full set of standard schema attributes.

class Colour(fields.Field):
    def _jsonschema_type_mapping(self):
        return {"type": "string"}

    def _serialize(self, value, attr, obj):
        r, g, b = value
        return "#%02X%02X%02X" % (r, g, b)


class UserSchema(Schema):
    favourite_colour = Colour(
        dump_default="#ffffff",
        metadata={"title": "Colour", "description": "Hex RGB"},
    )

For wrapper-style custom fields that need to re-enter the dumping machinery (e.g. to emit a $ref to a recursive schema), declare _jsonschema_type_mapping(self, json_schema, obj) with the two extra parameters and the JSONSchema instance + obj will be passed in.

React-JSONSchema-Form Extension

react-jsonschema-form renders JSON Schema as a React form. It accepts a separate uiSchema that controls presentation; this package's ReactJsonSchemaFormJSONSchema extension dumps both at once:

from marshmallow import Schema, fields
from marshmallow_jsonschema.extensions import ReactJsonSchemaFormJSONSchema

class MySchema(Schema):
    first_name = fields.String(metadata={"ui:autofocus": True})
    last_name = fields.String()

    class Meta:
        react_uischema_extra = {"ui:order": ["first_name", "last_name"]}


json_schema_obj = ReactJsonSchemaFormJSONSchema()
data = json_schema_obj.dump(MySchema())
ui_schema_json = json_schema_obj.dump_uischema(MySchema())

Contributing

Bug reports and pull requests are welcome. See CONTRIBUTING.md for local-dev setup and CONTRIBUTORS.md for the people who built this.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

marshmallow_jsonschema-0.15.0.tar.gz (36.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

marshmallow_jsonschema-0.15.0-py3-none-any.whl (16.7 kB view details)

Uploaded Python 3

File details

Details for the file marshmallow_jsonschema-0.15.0.tar.gz.

File metadata

  • Download URL: marshmallow_jsonschema-0.15.0.tar.gz
  • Upload date:
  • Size: 36.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.16

File hashes

Hashes for marshmallow_jsonschema-0.15.0.tar.gz
Algorithm Hash digest
SHA256 70af42e341094047b8dcf866bc845559f286109cd20a1818e28cd3dea127547d
MD5 a0d30d95a259f59baf0d3c75ca3d17e9
BLAKE2b-256 32c51eae50293abfd049b6a10468bdfed7c1a0bf1d9faaca76543fb115d2e069

See more details on using hashes here.

File details

Details for the file marshmallow_jsonschema-0.15.0-py3-none-any.whl.

File metadata

File hashes

Hashes for marshmallow_jsonschema-0.15.0-py3-none-any.whl
Algorithm Hash digest
SHA256 4ca49f49aca1ddbe0cd8f6a307495b8381da86f9dfa66108ffdd9fcd524e4356
MD5 b7c9965bcb727ccff001d3f7b48ee861
BLAKE2b-256 19c0274da65f0b5f41a8845b3d533a75223dd7da401a6bba59ebd34282d590c0

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page