JSON Schema Draft v7 (http://json-schema.org/) formatting with marshmallow
Project description
marshmallow-jsonschema: JSON Schema formatting with marshmallow
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(withmarshmallow<4)
Client tools that render forms from JSON Schema
- react-jsonschema-form (React; see the extension section below)
- json-editor (vanilla JS; used in
example/example.py)
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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
70af42e341094047b8dcf866bc845559f286109cd20a1818e28cd3dea127547d
|
|
| MD5 |
a0d30d95a259f59baf0d3c75ca3d17e9
|
|
| BLAKE2b-256 |
32c51eae50293abfd049b6a10468bdfed7c1a0bf1d9faaca76543fb115d2e069
|
File details
Details for the file marshmallow_jsonschema-0.15.0-py3-none-any.whl.
File metadata
- Download URL: marshmallow_jsonschema-0.15.0-py3-none-any.whl
- Upload date:
- Size: 16.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.16
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4ca49f49aca1ddbe0cd8f6a307495b8381da86f9dfa66108ffdd9fcd524e4356
|
|
| MD5 |
b7c9965bcb727ccff001d3f7b48ee861
|
|
| BLAKE2b-256 |
19c0274da65f0b5f41a8845b3d533a75223dd7da401a6bba59ebd34282d590c0
|