Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
jsonmodels / DESCRIPTION.rst
Size: Mime:
===========
JSON models
===========

.. image:: https://badge.fury.io/py/jsonmodels.png
    :target: http://badge.fury.io/py/jsonmodels

.. image:: https://travis-ci.org/beregond/jsonmodels.png?branch=master
    :target: https://travis-ci.org/beregond/jsonmodels

.. image:: https://img.shields.io/pypi/dm/jsonmodels.svg
    :target: https://pypi.python.org/pypi/jsonmodels

.. image:: https://coveralls.io/repos/beregond/jsonmodels/badge.png
    :target: https://coveralls.io/r/beregond/jsonmodels


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

* Free software: BSD license
* Documentation: http://jsonmodels.rtfd.org
* Source: https://github.com/beregond/jsonmodels

Features
--------

* Fully tested with Python 2.7, 3.3, 3.4, 3.5, 3.6.

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

* Create Django-like models:

  .. code-block:: python

    from jsonmodels import models, fields, errors, validators


    class Cat(models.Base):

        name = fields.StringField(required=True)
        breed = fields.StringField()
        love_humans = fields.IntField(nullable=True)


    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)
        nickname = fields.StringField(nullable=True)
        car = fields.EmbeddedField(Car)
        pets = fields.ListField([Cat, Dog], nullable=True)

* Access to values through attributes:

  .. code-block:: python

    >>> cat = Cat()
    >>> cat.populate(name='Garfield')
    >>> cat.name
    'Garfield'
    >>> cat.breed = 'mongrel'
    >>> cat.breed
    'mongrel'

* Validate models:

  .. code-block:: python

    >>> 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:

  .. code-block:: python

    >>> 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',
        'nickname': None,
        '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:

  .. code-block:: python

    >>> 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': ''},
                    'registration_number': {'type': 'string'}
                }
            },
            'surname': {'type': 'string'},
            'name': {'type': 'string'},
            'nickname': {'type': ['string', 'null']}
            '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': 'number'},
                                'name': {'type': 'string'}
                            }
                        },
                        {
                            'type': 'null'
                        }
                    ]
                },
                'type': 'array'
            }
        }
    }

* Validate models and use validators, that affect generated schema:

  .. code-block:: python

    >>> class Person(models.Base):
    ...
    ...     name = fields.StringField(
    ...         required=True,
    ...         validators=[
    ...             validators.Regex('^[A-Za-z]+$'),
    ...             validators.Length(3, 25),
    ...         ],
    ...     )
    ...     age = fields.IntField(
    ...         nullable=True,
    ...         validators=[
    ...             validators.Min(18),
    ...             validators.Max(101),
    ...         ]
    ...     )
    ...     nickname = fields.StringField(
    ...         required=True,
    ...         nullable=True
    ...     )
    ...

    >>> person = Person()
    >>> person.age = 11
    >>> person.validate()
    *** ValidationError: '11' is lower than minimum ('18').
    >>> person.age = None
    >>> person.validate()
    None

    >>> 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.nickname = None
    >>> person.validate()
    *** ValidationError: Field is required!

    >>> person.to_json_schema()
    {
        "additionalProperties": false,
        "properties": {
            "age": {
                "maximum": 101,
                "minimum": 18,
                "type": ["number", "null"]
            },
            "name": {
                "maxLength": 25,
                "minLength": 3,
                "pattern": "/^[A-Za-z]+$/",
                "type": "string"
            },
            "nickname": {,
                "type": ["string", "null"]
            }
        },
        "required": [
            "nickname",
            "name"
        ],
        "type": "object"
    }

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

* Lazy loading, best for circular references:

  .. code-block:: python

    >>> 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:

  .. code-block:: python

    >>> 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": "array"
            }
        },
        "additionalProperties": false,
        "definitions": {
            "directory": {
                "additionalProperties": false,
                "properties": {
                    "children": {
                        "items": {
                            "oneOf": [
                                "#/definitions/directory",
                                "#/definitions/file"
                            ]
                        },
                        "type": "array"
                    },
                    "name": {"type": "string"}
                },
                "type": "object"
            },
            "file": {
                "additionalProperties": false,
                "properties": {
                    "name": {"type": "string"},
                    "size": {"type": "number"}
                },
                "type": "object"
            }
        }
    }

* Compare JSON schemas:

  .. code-block:: python

    >>> from jsonmodels.utils import compare_schemas
    >>> schema1 = {'type': 'object'}
    >>> schema2 = {'type': 'array'}
    >>> 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.4 (2018-12-01)
++++++++++++++++

* Fixed length validator.
* Added Python 3.7 support.

2.3 (2018-02-04)
++++++++++++++++

* Added name mapping for fields.
* Added value parsing to IntField.
* Fixed bug with ECMA regex flags recognition.

2.2 (2017-08-21)
++++++++++++++++

* Fixed time fields, when value is not required.
* Dropped support for python 2.6
* Added support for python 3.6
* Added nullable param for fields.
* Improved model representation.

2.1.5 (2017-02-01)
++++++++++++++++++

* Fixed DateTimefield error when value is None.
* Fixed comparing models without required values.

2.1.4 (2017-01-24)
++++++++++++++++++

* Allow to compare models based on their type and fields (rather than their
  reference).

2.1.3 (2017-01-16)
++++++++++++++++++

* Fixed generated schema.
* Improved JSON serialization.

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.