Skip to main content

Models to make easier to deal with structures that are converted to, or read from JSON.

Project description

https://badge.fury.io/py/jsonmodels.png https://travis-ci.org/beregond/jsonmodels.png?branch=master https://img.shields.io/pypi/dm/jsonmodels.svg https://coveralls.io/repos/beregond/jsonmodels/badge.png

jsonmodels is library to make it easier for you to deal with structures that are converted to, or read from JSON.

Features

  • Fully tested with Python 2.6, 2.7, 3.2, 3.3, 3.4, 3.5.

  • Support for PyPy (see implementation notes in docs for more details).

  • Create Django-like models:

    from jsonmodels import models, fields, errors, validators
    
    
    class Cat(models.Base):
    
        name = fields.StringField(required=True)
        breed = fields.StringField()
    
    
    class Dog(models.Base):
    
        name = fields.StringField(required=True)
        age = fields.IntField()
    
    
    class Car(models.Base):
    
        registration_number = fields.StringField(required=True)
        engine_capacity = fields.FloatField()
        color = fields.StringField()
    
    
    class Person(models.Base):
    
        name = fields.StringField(required=True)
        surname = fields.StringField(required=True)
        car = fields.EmbeddedField(Car)
        pets = fields.ListField([Cat, Dog])
  • Access to values through attributes:

    >>> cat = Cat()
    >>> cat.populate(name='Garfield')
    >>> cat.name
    'Garfield'
    >>> cat.breed = 'mongrel'
    >>> cat.breed
    'mongrel'
  • Validate models:

    >>> person = Person(name='Chuck', surname='Norris')
    >>> person.validate()
    None
    
    >>> dog = Dog()
    >>> dog.validate()
    *** ValidationError: Field "name" is required!
  • Cast models to python struct and JSON:

    >>> cat = Cat(name='Garfield')
    >>> dog = Dog(name='Dogmeat', age=9)
    >>> car = Car(registration_number='ASDF 777', color='red')
    >>> person = Person(name='Johny', surname='Bravo', pets=[cat, dog])
    >>> person.car = car
    >>> person.to_struct()
    {
        'car': {
            'color': 'red',
            'registration_number': 'ASDF 777'
        },
        'surname': 'Bravo',
        'name': 'Johny',
        'pets': [
            {'name': 'Garfield'},
            {'age': 9, 'name': 'Dogmeat'}
        ]
    }
    
    >>> import json
    >>> person_json = json.dumps(person.to_struct())
  • You don’t like to write JSON Schema? Let jsonmodels do it for you:

    >>> person = Person()
    >>> person.to_json_schema()
    {
        'additionalProperties': False,
        'required': ['surname', 'name'],
        'type': 'object',
        'properties': {
            'car': {
                'additionalProperties': False,
                'required': ['registration_number'],
                'type': 'object',
                'properties': {
                    'color': {'type': 'string'},
                    'engine_capacity': {'type': 'float'},
                    'registration_number': {'type': 'string'}
                }
            },
            'surname': {'type': 'string'},
            'name': {'type': 'string'},
            'pets': {
                'items': {
                    'oneOf': [
                        {
                            'additionalProperties': False,
                            'required': ['name'],
                            'type': 'object',
                            'properties': {
                                'breed': {'type': 'string'},
                                'name': {'type': 'string'}
                            }
                        },
                        {
                            'additionalProperties': False,
                            'required': ['name'],
                            'type': 'object',
                            'properties': {
                                'age': {'type': 'integer'},
                                'name': {'type': 'string'}
                            }
                        }
                    ]
                },
                'type': 'list'
            }
        }
    }
  • Validate models and use validators, that affect generated schema:

    >>> class Person(models.Base):
    ...
    ...     name = fields.StringField(
    ...         required=True,
    ...         validators=[
    ...             validators.Regex('^[A-Za-z]+$'),
    ...             validators.Length(3, 25),
    ...         ],
    ...     )
    ...     age = fields.IntField(
    ...         required=True,
    ...         validators=[
    ...             validators.Min(18),
    ...             validators.Max(101),
    ...         ]
    ...     )
    
    >>> person = Person()
    >>> person.age = 11
    >>> person.validate()
    *** ValidationError: '11' is lower than minimum ('18').
    
    >>> person.age = 19
    >>> person.name = 'Scott_'
    >>> person.validate()
    *** ValidationError: Value "Scott_" did not match pattern "^[A-Za-z]+$".
    
    >>> person.name = 'Scott'
    >>> person.validate()
    None
    
    >>> person.to_json_schema()
    {
        "additionalProperties": false,
        "properties": {
            "age": {
                "maximum": 101,
                "minimum": 18,
                "type": "integer"
            },
            "name": {
                "maxLength": 25,
                "minLength": 3,
                "pattern": "/^[A-Za-z]+$/",
                "type": "string"
            }
        },
        "required": [
            "age",
            "name"
        ],
        "type": "object"
    }

    For more information, please see topic about validation in documentation.

  • Lazy loading, best for circular references:

    >>> class Primary(models.Base):
    ...
    ...     name = fields.StringField()
    ...     secondary = fields.EmbeddedField('Secondary')
    
    >>> class Secondary(models.Base):
    ...
    ...    data = fields.IntField()
    ...    first = fields.EmbeddedField('Primary')

    You can use either Model, full path path.to.Model or relative imports .Model or …Model.

  • Using definitions to generate schema for circular references:

    >>> class File(models.Base):
    ...
    ...     name = fields.StringField()
    ...     size = fields.FloatField()
    
    >>> class Directory(models.Base):
    ...
    ...     name = fields.StringField()
    ...     children = fields.ListField(['Directory', File])
    
    >>> class Filesystem(models.Base):
    ...
    ...     name = fields.StringField()
    ...     children = fields.ListField([Directory, File])
    
    >>> Filesystem.to_json_schema()
    {
        "type": "object",
        "properties": {
            "name": {"type": "string"}
            "children": {
                "items": {
                    "oneOf": [
                        "#/definitions/directory",
                        "#/definitions/file"
                    ]
                },
                "type": "list"
            }
        },
        "additionalProperties": false,
        "definitions": {
            "directory": {
                "additionalProperties": false,
                "properties": {
                    "children": {
                        "items": {
                            "oneOf": [
                                "#/definitions/directory",
                                "#/definitions/file"
                            ]
                        },
                        "type": "list"
                    },
                    "name": {"type": "string"}
                },
                "type": "object"
            },
            "file": {
                "additionalProperties": false,
                "properties": {
                    "name": {"type": "string"},
                    "size": {"type": "float"}
                },
                "type": "object"
            }
        }
    }
  • Compare JSON schemas:

    >>> from jsonmodels.utils import compare_schemas
    >>> schema1 = {'type': 'object'}
    >>> schema2 = {'type': 'list'}
    >>> compare_schemas(schema1, schema1)
    True
    >>> compare_schemas(schema1, schema2)
    False

More

For more examples and better description see full documentation: http://jsonmodels.rtfd.org.

History

2.1.2 (2016-01-06)

  • Fixed memory leak.

2.1.1 (2015-11-15)

  • Added support for Python 2.6, 3.2 and 3.5.

2.1 (2015-11-02)

  • Added lazy loading of types.

  • Added schema generation for circular models.

  • Improved readability of validation error.

  • Fixed structure generation for list field.

2.0.1 (2014-11-15)

  • Fixed schema generation for primitives.

2.0 (2014-11-14)

  • Fields now are descriptors.

  • Empty required fields are still validated only during explicite validations.

Backward compatibility breaks

  • Renamed _types to types in fields.

  • Renamed _items_types to items_types in ListField.

  • Removed data transformers.

  • Renamed module error to errors.

  • Removed explicit validation - validation occurs at assign time.

  • Renamed get_value_replacement to get_default_value.

  • Renamed modules utils to utilities.

1.4 (2014-07-22)

  • Allowed validators to modify generated schema.

  • Added validator for maximum value.

  • Added utilities to convert regular expressions between Python and ECMA formats.

  • Added validator for regex.

  • Added validator for minimum value.

  • By default “validators” property of field is an empty list.

1.3.1 (2014-07-13)

  • Fixed generation of schema for BoolField.

1.3 (2014-07-13)

  • Added new fields (BoolField, TimeField, DateField and DateTimeField).

  • ListField is always not required.

  • Schema can be now generated from class itself (not from an instance).

1.2 (2014-06-18)

  • Fixed values population, when value is not dictionary.

  • Added custom validators.

  • Added tool for schema comparison.

1.1.1 (2014-06-07)

  • Added possibility to populate already initialized data to EmbeddedField.

  • Added compare_schemas utility.

1.1 (2014-05-19)

  • Added docs.

  • Added json schema generation.

  • Added tests for PEP8 and complexity.

  • Moved to Python 3.4.

  • Added PEP257 compatibility.

  • Added help text to fields.

1.0.5 (2014-04-14)

  • Added data transformers.

1.0.4 (2014-04-13)

  • List field now supports simple types.

1.0.3 (2014-04-10)

  • Fixed compatibility with Python 3.

  • Fixed str and repr methods.

1.0.2 (2014-04-03)

  • Added deep data initialization.

1.0.1 (2014-04-03)

  • Added populate method.

1.0 (2014-04-02)

  • First stable release on PyPI.

0.1.0 (2014-03-17)

  • First release on PyPI.

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

jsonmodels-2.1.2.tar.gz (17.5 kB view details)

Uploaded Source

Built Distribution

jsonmodels-2.1.2-py2.py3-none-any.whl (18.3 kB view details)

Uploaded Python 2 Python 3

File details

Details for the file jsonmodels-2.1.2.tar.gz.

File metadata

  • Download URL: jsonmodels-2.1.2.tar.gz
  • Upload date:
  • Size: 17.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No

File hashes

Hashes for jsonmodels-2.1.2.tar.gz
Algorithm Hash digest
SHA256 91c1823a1a4aa5a0ca6c77048aa66f9524accaaf654d9ea17b875d806b59b895
MD5 5d5db82e30a9f8ccb7aee30e24e617da
BLAKE2b-256 249fe98201eb51a973743523bedeec8a364bc25b43b406a988f18cf7f2762b73

See more details on using hashes here.

File details

Details for the file jsonmodels-2.1.2-py2.py3-none-any.whl.

File metadata

File hashes

Hashes for jsonmodels-2.1.2-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 7683ed1996be7aa06d61c84700022f07ccf5590428474238cdf1a0893d9f219c
MD5 99eb0acd9fc42f84deff1afbbe3e7e01
BLAKE2b-256 72574b0af2f7d5381f0a435b362c2de8702c55adf518f75f20b5b2afc3841a21

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