Skip to main content

JSON schema generation from dataclasses

Project description

https://travis-ci.org/s-knibbs/dataclasses-jsonschema.svg?branch=master https://badge.fury.io/py/dataclasses-jsonschema.svg Language grade: Python

A library to generate JSON Schema from python 3.7 dataclasses. Python 3.6 is supported through the dataclasses backport. Aims to be a more lightweight alternative to similar projects such as marshmallow & pydantic.

Feature Overview

  • Support for draft-04, draft-06, Swagger 2.0 & OpenAPI 3 schema types

  • Serialisation and deserialisation

  • Data validation against the generated schema

  • APISpec support. Example below:

Installation

~$ pip install dataclasses-jsonschema

For improved validation performance using fastjsonschema, install with:

~$ pip install dataclasses-jsonschema[fast-validation]

Examples

from dataclasses import dataclass

from dataclasses_jsonschema import JsonSchemaMixin


@dataclass
class Point(JsonSchemaMixin):
    "A 2D point"
    x: float
    y: float

Generate the schema:

>>> pprint(Point.json_schema())
{
    'description': 'A 2D point',
    'type': 'object',
    'properties': {
        'x': {'format': 'float', 'type': 'number'},
        'y': {'format': 'float', 'type': 'number'}
    },
    'required': ['x', 'y']
}

Serialise data:

>>> Point(x=3.5, y=10.1).to_dict()
{'x': 3.5, 'y': 10.1}

Deserialise data:

>>> Point.from_dict({'x': 3.14, 'y': 1.5})
Point(x=3.14, y=1.5)
>>> Point.from_dict({'x': 3.14, y: 'wrong'})
dataclasses_jsonschema.ValidationError: 'wrong' is not of type 'number'

Generate a schema for embedding into an API spec:

from dataclasses_jsonschema import JsonSchemaMixin, SchemaType

@dataclass
class Address(JsonSchemaMixin):
    """Postal Address"""
    building: str
    street: str
    city: str

@dataclass
class Company(JsonSchemaMixin):
    """Company Details"""
    name: str
    address: Address

>>> pprint(JsonSchemaMixin.all_json_schemas(schema_type=SchemaType.SWAGGER_V3))
{'Address': {'description': 'Postal Address',
             'properties': {'building': {'type': 'string'},
                            'city': {'type': 'string'},
                            'street': {'type': 'string'}},
             'required': ['building', 'street', 'city'],
             'type': 'object'},
 'Company': {'description': 'Company Details',
             'properties': {'address': {'$ref': '#/components/schemas/Address'},
                            'name': {'type': 'string'}},
             'required': ['name', 'address'],
             'type': 'object'}}

Custom validation rules can be added using NewType:

from dataclasses_jsonschema import JsonSchemaMixin, FieldEncoder

PhoneNumber = NewType('PhoneNumber', str)

class PhoneNumberField(FieldEncoder):

    @property
    def json_schema(self):
        return {'type': 'string', 'pattern': r'^(\([0-9]{3}\))?[0-9]{3}-[0-9]{4}$'}

JsonSchemaMixin.register_field_encoders({PhoneNumber: PhoneNumberField()})

@dataclass
class Person(JsonSchemaMixin):
    name: str
    phone_number: PhoneNumber

For more examples see the tests

APISpec Plugin

New in v2.5.0

OpenAPI & Swagger specs can be generated using the apispec plugin:

from typing import Optional, List
from dataclasses import dataclass

from apispec import APISpec
from apispec_webframeworks.flask import FlaskPlugin
from flask import Flask, jsonify
import pytest

from dataclasses_jsonschema.apispec import DataclassesPlugin
from dataclasses_jsonschema import JsonSchemaMixin


# Create an APISpec
spec = APISpec(
    title="Swagger Petstore",
    version="1.0.0",
    openapi_version="3.0.2",
    plugins=[FlaskPlugin(), DataclassesPlugin()],
)


@dataclass
class Category(JsonSchemaMixin):
    """Pet category"""
    name: str
    id: Optional[int]

@dataclass
class Pet(JsonSchemaMixin):
    """A pet"""
    categories: List[Category]
    name: str


app = Flask(__name__)


@app.route("/random")
def random_pet():
    """A cute furry animal endpoint.
    ---
    get:
      description: Get a random pet
      responses:
        200:
          content:
            application/json:
              schema: Pet
    """
    pet = get_random_pet()
    return jsonify(pet.to_dict())

# Dependant schemas (e.g. 'Category') are added automatically
spec.components.schema("Pet", schema=Pet)
with app.test_request_context():
    spec.path(view=random_pet)

TODO

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

dataclasses-jsonschema-2.6.0.tar.gz (21.1 kB view details)

Uploaded Source

File details

Details for the file dataclasses-jsonschema-2.6.0.tar.gz.

File metadata

  • Download URL: dataclasses-jsonschema-2.6.0.tar.gz
  • Upload date:
  • Size: 21.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.19.1 setuptools/40.0.0 requests-toolbelt/0.9.1 tqdm/4.31.1 CPython/3.6.5

File hashes

Hashes for dataclasses-jsonschema-2.6.0.tar.gz
Algorithm Hash digest
SHA256 4d791e88e2f049fbdc0e3492b0654bc6a447bc2c193dc072955adf28f2295bf6
MD5 22f8e5c800faa3f12a23cf4acaedf6dd
BLAKE2b-256 27d29bd5405d348b95d5cd2368b5e1e92716bf9387604cb15c9846d02eb535c3

See more details on using hashes here.

Supported by

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