Convert a JSON schema to a python class [closed]
Asked Answered
E

5

51

Is there a python library for converting a JSON schema to a python class definition, similar to jsonschema2pojo -- https://github.com/joelittlejohn/jsonschema2pojo -- for Java?

Euchologion answered 17/9, 2012 at 19:5 Comment(3)
Can you elaborate on why the functionality of the json standard library module isn't sufficient for your needs and you require the generated class definitions?Pyuria
The answer to your comment is pretty simple - working with raw dictionaries is second class object management and most people don't like the curly-bracket shotgun blast to the face that JSON provides.Forrest
I would love an answer to this question that had a code generator (compiler) for the classes, rather than the current approaches, which do not produce class definition code, but only class definitions in the state of the interpreter. jsonschema2popo is more of a sketch than an answer. The OpenAPI generator does this compilation process, but only in the context of an API definition -- it won't make standalone JSON schema translations (AFAICT).Mcghee
F
37

So far the closest thing I've been able to find is warlock, which advertises this workflow:

Build your schema

>>> schema = {
    'name': 'Country',
    'properties': {
        'name': {'type': 'string'},
        'abbreviation': {'type': 'string'},
    },
    'additionalProperties': False,
}

Create a model

>>> import warlock
>>> Country = warlock.model_factory(schema)

Create an object using your model

>>> sweden = Country(name='Sweden', abbreviation='SE')

However, it's not quite that easy. The objects that Warlock produces lack much in the way of introspectible goodies. And if it supports nested dicts at initialization, I was unable to figure out how to make them work.

To give a little background, the problem that I was working on was how to take Chrome's JSONSchema API and produce a tree of request generators and response handlers. Warlock doesn't seem too far off the mark, the only downside is that meta-classes in Python can't really be turned into 'code'.

Other useful modules to look for:

If you end up finding a good one-stop solution for this please follow up your question - I'd love to find one. I poured through github, pypi, googlecode, sourceforge, etc.. And just couldn't find anything really sexy.

For lack of any pre-made solutions, I'll probably cobble together something with Warlock myself. So if I beat you to it, I'll update my answer. :p

Forrest answered 1/11, 2012 at 17:25 Comment(1)
Ditto on following up. I went through the same sources and couldn't find any acceptable solution. I even forked warlock and started working on implementing recursion in their class definition (which seems like it should be fairly easy), but gave up.Matildematin
A
26

python-jsonschema-objects is an alternative to warlock, build on top of jsonschema

python-jsonschema-objects provides an automatic class-based binding to JSON schemas for use in python.

Usage:

Sample Json Schema

schema = '''{
    "title": "Example Schema",
    "type": "object",
    "properties": {
        "firstName": {
            "type": "string"
        },
        "lastName": {
            "type": "string"
        },
        "age": {
            "description": "Age in years",
            "type": "integer",
            "minimum": 0
        },
        "dogs": {
            "type": "array",
            "items": {"type": "string"},
            "maxItems": 4
        },
        "gender": {
            "type": "string",
            "enum": ["male", "female"]
        },
        "deceased": {
            "enum": ["yes", "no", 1, 0, "true", "false"]
            }
    },
    "required": ["firstName", "lastName"]
} '''

Converting the schema object to class

 import python_jsonschema_objects as pjs
 import json
 schema = json.loads(schema)   
 builder = pjs.ObjectBuilder(schema)   
 ns = builder.build_classes()   
 Person = ns.ExampleSchema   
 james = Person(firstName="James", lastName="Bond")   
 james.lastName  
  u'Bond'  james      
 example_schema lastName=Bond age=None firstName=James  

Validation :

james.age = -2 python_jsonschema_objects.validators.ValidationError: -2 was less or equal to than 0

But problem is , it is still using draft4validation while jsonschema has moved over draft4validation , i filed an issue on the repo regarding this . Unless you are using old version of jsonschema , the above package will work as shown.

Axial answered 16/10, 2014 at 7:35 Comment(4)
Worth noting that python-jsonschema-objects supports JSON Schema Draft-4Armada
Looks like python-jsonschema-objects cannot emit class definitions in files, so it's hard to know what is going on with these, they are not easily used in type declarations, etc. It would be nice if class definitions could be written as source code.Mcghee
@RobertP.Goldman could you elaborate a little? Do you mean you can't get auto complete for them? Will mypy reject them?Bugleweed
@Bugleweed -- I have worked with a class generator like this from RDF, and I absolutely hate it. You can't really see the class definitions except through cumbersome introspection and, AFAICT you can't use them for type declarations, etc. Also, at least the codebase I was working with didn't seem to enable loading them -- instead it would re-derive the classes every time it started up (I'm not sure if this was a limitation of the library or my colleagues' codebase). I'm a big fan of being able to read the code, so I don't like these things that are only in working memory.Mcghee
J
7

datamodel-code-generator is a cli code generator that can build pydantic models and dataclasses.dataclass from various sources including JSON schema.

At the time of writing it has a lot more users according to GitHub than the libraries in other answers

Example usage to generate python dataclasses from a json schema:

datamodel-codegen --input ./<your-data-here>.json --input-file-type jsonschema --output <your-data-here>.py --output-model-type dataclasses.dataclass
Joyjoya answered 26/5, 2023 at 15:49 Comment(1)
I tried this library on the Overture Maps schema and it basically failed. It was able to output the GeoJSON types but didn't emit anything for the Overture data types. There were no warnings or logs, and I didn't find the -debug option to generate anything useful. So it's a mystery why it didn't work, albeit the Overture schema is fairly complex.Irs
M
3

I just created this small project to generate code classes from json schema, even if dealing with python I think can be useful when working in business projects:

pip install jsonschema2popo

running following command will generate a python module containing json-schema defined classes (it uses jinja2 templating)

jsonschema2popo -o /path/to/output_file.py /path/to/json_schema.json

more info at: https://github.com/frx08/jsonschema2popo

Menfolk answered 16/3, 2018 at 9:37 Comment(2)
The library does what it promises, but has silly assumptions, bugs, and typos. All addressable but far from polished.Lonergan
Downgraded this answer because jsonschema2popo is riddled with bugs, and seems bitrotted.Mcghee
C
0

We are big fans of using https://quicktype.io. They have a npm installer, run from command line, and put your entire datamodel into JSON-Schema.

If you need to use it for sensitive company data turn on the --no telemetry option.

This will also generate all of the classes you will need for all the other languages as well.

Chaldean answered 9/4 at 0:22 Comment(3)
While the information in your link may solve the OP's question, answers that rely heavily on links are discouraged for these reasons. Please consider updating your answer so that it is self-contained, with the minimal amount of code required to demonstrate how your suggestion can be implemented. Thanks.Cw
"They have a npm installer"—this question is tagged for Python.Eisteddfod
NPM will install their cli tool. Then you can use python subprocess to call -- but this is rather inefficient and we use shell to script these. However I think this guy's goal is to take schema and make python class -- of which quicktype is one of the most friendly. not necessarily needing it to be as he asks "a python library". Give their live tool a gander: app.quicktype.io and choose python as the output type, and json-schema as the input type.Chaldean

© 2022 - 2024 — McMap. All rights reserved.