aromanovich / jsl

A Python DSL for describing JSON schemas
http://jsl.readthedocs.org/
Other
218 stars 21 forks source link

Inheritance #13

Closed erikvanzijst closed 8 years ago

erikvanzijst commented 8 years ago

I'm trying to generate a schema that encodes inheritance using allOf in a subtype to merge the properties from a base type. However, I'm having trouble figuring out how to do this in jsl.

Is it possible to have jsl generate something along the following lines?

    {
      "$ref": "#/definitions/circle",
      "definitions": {
        "shape": {
          "type": "object",
          "properties": {
            "color": {
              "type": "string"
            }
          }
        },
        "circle": {
          "type": "object",
          "allOf": [
            {
              "$ref": "#/definitions/shape"
            },
            {
              "properties": {
                "radius": {
                  "type": "number"
                }
              }
            }
          ]
        }
      }
    }

Note that I want to the schema to explicitly encode the relationship between shape and circle, instead of ending up with 2 independent objects where circle contains its own, inline copy of the color element.

aromanovich commented 8 years ago

I'm on it. I will release a new version in a couple of days with the support for allOf-inheritance.

erikvanzijst commented 8 years ago

Sweet!

aromanovich commented 8 years ago

I've released the 0.1.4 version on PyPI. It introduces the notion of inheritance modes. All you need to generate such a schema is to set the inheritance_mode option to jsl.ALL_OF:

>>> class Shape(jsl.Document):
...     class Options(object):
...         definition_id = 'shape'
...         title = 'Shape'
...     color = jsl.StringField(required=True)
...
>>> class Circle(Shape):
...     class Options(object):
...         definition_id = 'circle'
...         title = 'Circle'
...         inheritance_mode = jsl.ALL_OF
...     radius = jsl.NumberField(required=True)
>>> print json.dumps(Circle.get_schema(ordered=True), indent=4)
{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "definitions": {
        "shape": {
            "type": "object",
            "title": "Shape",
            "properties": {
                "color": {
                    "type": "string"
                }
            },
            "required": [
                "color"
            ],
            "additionalProperties": false
        }
    },
    "allOf": [
        {
            "$ref": "#/definitions/shape"
        },
        {
            "type": "object",
            "title": "Circle",
            "properties": {
                "radius": {
                    "type": "number"
                }
            },
            "required": [
                "radius"
            ],
            "additionalProperties": false
        }
    ]
}