Skip to main content

JSON schema Utils

Project description

ju

JSON schema Utils

To install: pip install ju

Documentation

Examples

JSON Schema

You have tools to extract JSON schema information from python objects, as well as to create python objects from them.

>>> from ju import signature_to_json_schema, json_schema_to_signature
>>>
>>>
>>> def earth(north: str, south: bool, east: int = 1, west: float = 2.0):
...     """Earth docs"""
...     return f'{north=}, {south=}, {east=}, {west=}'
...
>>> schema = signature_to_json_schema(earth)
>>> assert schema == {
...     'description': 'Earth docs',
...     'title': 'earth',
...     'type': 'object',
...     'properties': {
...         'north': {'type': 'string'},
...         'south': {'type': 'boolean'},
...         'east': {'type': 'integer', 'default': 1},
...         'west': {'type': 'number', 'default': 2.0},
...     },
...     'required': ['north', 'south'],
... }
>>>
>>> sig = json_schema_to_signature(schema)
>>> sig
<Sig (north: str, south: bool, east: int = 1, west: float = 2.0)>
>>> sig.name
'earth'
>>> sig.docs
'Earth docs'

React JSON Schema Form (rjsf)

You can get a react-jsonschema-form (rjsf) specification (see the rjsf playground) from a python function.

>>> def foo(
    ...     a_bool: bool,
    ...     a_float=3.14,
    ...     an_int=2,
    ...     a_str: str = 'hello',
    ...     something_else=None
    ... ):
    ...     '''A Foo function'''
    >>>
    >>> form_spec = func_to_form_spec(foo)
    >>> assert form_spec == {
    ...     'rjsf': {
    ...         'schema': {
    ...             'title': 'foo',
    ...             'type': 'object',
    ...             'properties': {
    ...                 'a_bool': {'type': 'boolean'},
    ...                 'a_float': {'type': 'number', 'default': 3.14},
    ...                 'an_int': {'type': 'integer', 'default': 2},
    ...                 'a_str': {'type': 'string', 'default': 'hello'},
    ...                 'something_else': {'type': 'string', 'default': None}
    ...             },
    ...             'required': ['a_bool'],
    ...             'description': 'A Foo function'
    ...         },
    ...         'uiSchema': {
    ...             'ui:submitButtonOptions': {
    ...                 'submitText': 'Run'
    ...             },
    ...             'a_bool': {'ui:autofocus': True}
    ...         },
    ...         'liveValidate': False,
    ...         'disabled': False,
    ...         'readonly': False,
    ...         'omitExtraData': False,
    ...         'liveOmit': False,
    ...         'noValidate': False,
    ...         'noHtml5Validate': False,
    ...         'focusOnFirstError': False,
    ...         'showErrorList': 'top'
    ...     }
    ... }

OpenAPI Routes

Represents a collection of routes in an OpenAPI specification.

Each instance of this class contains a list of Route objects, which can be accessed and manipulated as needed.

>>> from yaml import safe_load
>>> spec_yaml = '''
... openapi: 3.0.3
... paths:
...   /items:
...     get:
...       summary: List items
...       responses:
...         '200':
...           description: An array of items
...     post:
...       summary: Create item
...       responses:
...         '201':
...           description: Item created
... '''
>>> spec = safe_load(spec_yaml)
>>> routes = Routes(spec)
>>> len(routes)
2
>>> list(routes)
[('get', '/items'), ('post', '/items')]
>>> r = routes['get', '/items']
>>> r
Route(method='get', endpoint='/items')
>>> r.method_data
{'summary': 'List items', 'responses': {'200': {'description': 'An array of items'}}}

pydantic utils

The ju.pydantic_util module provides comprehensive tools for working with Pydantic models and JSON schemas.

Creating Models from Data and Schemas

Generate Pydantic models dynamically from data or JSON schemas:

from ju.pydantic_util import data_to_pydantic_model, schema_to_pydantic_model

# Create model from data dictionary
data = {"name": "Alice", "age": 30, "address": {"city": "NYC", "zip": "10001"}}
UserModel = data_to_pydantic_model(data, "User")

# Create model from JSON schema
schema = {
    "type": "object",
    "properties": {
        "title": {"type": "string"},
        "price": {"type": "number"}
    }
}
ProductModel = schema_to_pydantic_model(schema)

Model Validation and Selection

Check data validity and find matching models:

from ju.pydantic_util import is_valid_wrt_model, valid_models

# Check if data is valid for a specific model
is_valid = is_valid_wrt_model({"name": "Bob", "age": 25}, UserModel)

# Find all models that validate given data
models = [UserModel, ProductModel, AdminModel]
matching = list(valid_models(data, models))

Code Generation with Transformations

Convert models and schemas to Python code with optional transformations:

from ju.pydantic_util import pydantic_model_to_code

# Generate code from model
code = pydantic_model_to_code(UserModel)

# Apply transformations during generation
def fix_field_names(schema):
    # Transform problematic field names
    if 'properties' in schema:
        for old_name, new_name in [('class_', 'class_name'), ('type_', 'type_name')]:
            if old_name in schema['properties']:
                schema['properties'][new_name] = schema['properties'].pop(old_name)
    return schema

code = pydantic_model_to_code(
    source_schema, 
    ingress_transform=fix_field_names,
    egress_transform=lambda code: f"# Auto-generated\n{code}"
)

Model Introspection and Data Extraction

Extract structured information about models and use them as data extraction templates:

from ju.pydantic_util import (
    field_paths_and_annotations, 
    model_field_descriptions,
    ModelExtractor
)

# Get flattened field paths and types
paths = field_paths_and_annotations(UserModel)
# {'name': str, 'age': int, 'address.city': str, 'address.zip': str}

# Extract field descriptions
descriptions = model_field_descriptions(UserModel)

# Use models as data extraction templates
extractor = ModelExtractor([UserModel, AdminModel])
data_reader = extractor(json_data)  # Returns mapping with model-based paths
values = data_reader['address.city']  # Extract nested values easily

The module handles complex scenarios like nested models, generic types, collections, and provides flexible validation and transformation capabilities.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ju-0.1.31.tar.gz (44.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ju-0.1.31-py3-none-any.whl (47.5 kB view details)

Uploaded Python 3

File details

Details for the file ju-0.1.31.tar.gz.

File metadata

  • Download URL: ju-0.1.31.tar.gz
  • Upload date:
  • Size: 44.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.18

File hashes

Hashes for ju-0.1.31.tar.gz
Algorithm Hash digest
SHA256 f2076e2e0a0b7307778e6395efe47bbc181ff79c048ed5aa05b54742abb820b6
MD5 cbdd10c05c3330281a6c92088d365026
BLAKE2b-256 fe2743a40739d8db63f2d5ac19e8236049d10f293f05888f2636480ebfdc4243

See more details on using hashes here.

File details

Details for the file ju-0.1.31-py3-none-any.whl.

File metadata

  • Download URL: ju-0.1.31-py3-none-any.whl
  • Upload date:
  • Size: 47.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.18

File hashes

Hashes for ju-0.1.31-py3-none-any.whl
Algorithm Hash digest
SHA256 948da279e1040f2b6849fc6f55e0b43e59dc53e2b39ffef0d9cc22b00830f803
MD5 1ccadb93bcc041ca6c7f2dfffbcb8e97
BLAKE2b-256 e179e609ad36ef1082e0c2c02d3bdb31daa71996cdab5b9cf05b632c14a6f63f

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page