Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/beregond/jsonmodels

jsonmodels is library to make it easier for you to deal with structures that are converted to, or read from JSON.
https://github.com/beregond/jsonmodels

Last synced: 3 months ago
JSON representation

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

Awesome Lists containing this project

README

        

===========
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.