JSONSchema generation from Python type hints
Project description
jsonschema-gen is Python type hints parser which can convert function and method annotations into JSONSchema objects.
- Pythonic JSONSchema objects
- Extensive type coverage: TypedDict, Generic, NewType, etc.
- No external dependencies
Use
Initially it was created to auto-generate documentation schemas for our JSONRPC API.
The process is quite simple: initialize a jsonschema_gen.Parser
and pass your class and method there. The result
is a namedtuple with kwargs
attribute containing a JSONSchema object with all the input parameters, and
returns
attribute with the return parameter schema.
from typing import NewType, TypedDict
from jsonschema_gen import Parser
Username = NewType('Username', str)
class User(TypedDict):
name: str
blocked: bool
class UserData:
def get_user(self, name: Username) -> User:
...
parser = Parser()
annotations = parser.parse_function(UserData, UserData.get_user)
# annotation.kwargs - input
# annotation.returns - output
To get a JSON-compatible dictionary use annotation.kwargs.get_jsonschema()
method on kwargs
.
In the aforementioned case the result would look like this (if you dump it with json.dumps
)
(note that the value of annotation.kwargs
may be None
if there are no input params in your function)
{
"type": "object",
"properties": {
"name": {
"title": "Username",
"type": "string"
}
},
"required": [
"name"
],
"additionalProperties": false
}
and for the return value in annotation.returns.get_jsonschema()
:
{
"type": "object",
"title": "User",
"properties": {
"name": {
"type": "string"
},
"blocked": {
"type": "boolean"
}
},
"required": [
"name",
"blocked"
],
"additionalProperties": false
}
If you need to use this schema for validation, you can install any type of JSONSchema validators, such as
fastjsonschema and use them with the resulting kwargs
.
from fastjsonschema import compile
validator = compile(annotations.kwargs.get_jsonschema())
validator({'name': 'John Dowe'})
Limitations
The two types of limitations can be split in ones imposed by JSONSchema and the limitations of this library.
There's no proper way describe a mixed set of positional and keyword input parameters in JSONSchema. In such cases all positional variable arguments will be skipped by the parser, and positional-only parameters will cause an error.
# '*args' will be skipped
def func_1(value: str, *args, flag: bool = True): ...
# 'value' will cause an error
def func_2(value: str, /, flag: bool = True): ...
Variable keyword arguments will be converted to additionalProperties=true
in JSONSchema.
# '*kwargs' will set 'additionalProperties' to 'true', 'value' is still required
def func_1(value: str, **kwargs): ...
Strict mode
There are two methods of using jsonschema_gen.Parser
. By default, it uses the strict mode, which means
an implicit type or any non-JSON compatible type will cause an error.
For example, the UUID
or datetime
type is not a valid JSON type, but rather just a string format, so this type
of type hint will cause an error in strict mode. In non-strict mode it will be converted to a string with
format="uuid"
/ format="date-time"
respectively.
Some JSON parsers like orjson can in fact parse date-time strings to Python datetime
type. In this case you may either switch to non-strict mode or modify a particular type parser to
allow it in the strict mode.
from jsonschema_gen.parsers import DateTimeParser, DateParser
DateTimeParser.strict = True
DateParser.strict = True
Compatibility
The Python type hints are vast and yet not well organized, so there could always be some data type I forgot to add here. You can use the extension guide to extend the standard list of type parsers.
Python 3.8 compatibility is so-so due to lots of features and changes made in 3.9. However, it still should support most of the functionality.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distribution
Hashes for jsonschema_gen-0.1.0-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 5634d0eabebae3d9dd6bdeec56b49d008c1d064b3a48d00e5da1da1f18dfc7f0 |
|
MD5 | 5013ecc3493f000096ccaf13e22197bc |
|
BLAKE2b-256 | 7fd60eda660e4fad6c34dc7b829dfd96cdbf8aaf523a3dcd3d7248c61bc67280 |