Skip to main content

Test

pytojsonschema

Package that uses static analysis - ast - to convert Python 3 function type annotations to JSON schemas.

This allows you to auto-generate the validation schemas for JSON-RPC backend functions written in Python.

Current support is for Python 3.8+ and JSON schema draft 7+.

Getting started

Installation

From a Python 3.8+ environment, run pip install pytojsonschema.

Scan a package

After installing the package, you can open a python terminal from the root of the repo and run:

import os
import pprint

from pytojsonschema.functions import process_package

pprint.pprint(process_package(os.path.join("test", "example")))

The example package will be scanned and JSON schemas will be generated for all the top level functions it can find.

Scan a file

You can also target specific files, which won't include the package namespacing in the result value. Following on the same terminal:

from pytojsonschema.functions import process_file

pprint.pprint(process_file(os.path.join("test", "example", "service.py")))

Include and exclude patterns

Include and exclude unix-like patterns can be used to filter function and module names we want to allow/disallow for scanning. See the difference when you now run this instead:

pprint.pprint(process_package(os.path.join("test", "example"), exclude_patterns=["_*"]))

Similarly, but applied to specific files:

pprint.pprint(process_file(os.path.join("test", "example", "service.py"), exclude_patterns=["_*"]))

Things to take into account:

  • Exclude pattern matching overwrite include matches.
  • __init__.py files are not affected by pattern rules and are always scanned. However, you can still filter its internal functions.

Type annotation rules

Fitting Python's typing model to JSON means not everything is allowed in your function signatures. This is a natural restriction that comes with JSON data serialization. Hopefully, most of the useful stuff you need is allowed.

Allowed types

Base types

Basic types bool, int, float, str, None and typing.Any are allowed. Also, you can build more complex, nested structures with the usage of typing.Union, typing.Optional, typing.Dict (Only str keys are allowed) and typing.List. All these types have a direct, non-ambiguous representation in both JSON and JSON schema.

Custom types

Your functions can also use custom types like the ones defined using an assignment of typing.Union, typing.List, typing.Dict and typing.Optional, as in:

ServicePort = typing.Union[int, float]
ServiceConfig = typing.Dict[str, typing.Any]

You can use one of the new Python 3.8 features, typing.TypedDict, to build stronger validation on dict-like objects (Only class-based syntax). As you can see, you can chain types with no restrictions:

class Service(typing.TypedDict):
    address: str
    port: ServicePort
    config: ServiceConfig
    tags: typing.List[str]
    debug: bool = False

Note: Whilst Python itself will not auto-populate default values, you can use them to make the property not required.

Also, if you need to restrict the choices for a type, you can use Python enums:

import enum


class HTTPMethod(enum.Enum):
    GET = "GET"
    POST = "POST"
    PATCH = "PATCH"
    DELETE = "DELETE"


def my_func(http_method: HTTPMethod):
    pass  # My code

Note: All properties of the enum must be constants: None, int, float, bool, str.

Note: The resulting validation uses the different enum values, e.g. HTTPMethod.GET.value or simply "GET", as the valid choices and not the enum instance itself, e.g. HTTPMethod.GET, as that is what JSON schema can understand. This can lead to some incompatibilities with other static analysis tools like http://mypy-lang.org/, so bear that in mind.

Importing types from other files

You can import these custom types within your package and they will be picked up. However, due to the static nature of the scan, custom types coming from external packages can't be followed and hence not supported. In other words, you can only share these types within your package, using relative imports.

Other static analysis tools like mypy use a repository with stub files to solve this issue, see https://mypy.readthedocs.io/en/stable/stubs.html. This is out of the scope for a tiny project like this, at least for now.

Rules

  1. The functions you want to scan need to be type annotated. Kind of obvious requirement, right?

  2. Only the types defined in the previous section can be used. They are the types that can be safely serialised as JSON.

  3. Function arguments are meant to be passed in key-value format, like a json object. This puts a couple of restrictions regarding *args, **kwargs, positional-only and keyword-only arguments:

    The following is allowed:

    • **kwargs: def func(**kwargs): pass
    • keyword-only arguments: def func(*, a): pass

    The following is not allowed:

    • *args: def func(*args): pass
    • positional-only arguments: def func(a, /): pass

Release files for pytojsonschema 1.11.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pytojsonschema 1.11.1
File Size Uploaded
pytojsonschema-1.11.1.tar.gz 15.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pytojsonschema 1.11.1
File Interpreter ABI Platform
pytojsonschema-1.11.1-py3-none-any.whl Python 3 none any Details

Total release size: 27.3 kB

Release files / pytojsonschema-1.11.1.tar.gz

Download URL pytojsonschema-1.11.1.tar.gz
Size 15.5 kB
Tags Source
SHA-256 checksum
How to use checksums
bc9ca62a8870f615b52e514ea54f0a0da7d622055d7d15bd395b2d4b61d6332a
BLAKE2b-256 checksum
How to use checksums
f2b0c3034479040e05ea111a7e6cded4d8a0229e246e4e0697b10710be0e283e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.2.0 pkginfo/1.6.1 requests/2.24.0 setuptools/49.2.1 requests-toolbelt/0.9.1 tqdm/4.51.0 CPython/3.9.0

Release files / pytojsonschema-1.11.1-py3-none-any.whl

Download URL pytojsonschema-1.11.1-py3-none-any.whl
Size 11.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
67eb4de6cf69fe85aa305c399b897dce817fad83b95088becf004ba54d7fd5e3
BLAKE2b-256 checksum
How to use checksums
c17db72c7c14a1f7ac6ed22af995d6d6e0a908cc9f5e71382ab8240af75258ec
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.2.0 pkginfo/1.6.1 requests/2.24.0 setuptools/49.2.1 requests-toolbelt/0.9.1 tqdm/4.51.0 CPython/3.9.0

Release history Release notifications | RSS feed

This release

1.11.1 This release

2 release files

1.10.1

2 release files

1.10.0

2 release files

1.0.9

2 release files

1.0.8

2 release files

1.0.7

2 release files

1.0.6

2 release files

1.0.5

2 release files

1.0.4

2 release files

1.0.3

2 release files

1.0.2

2 release files

1.0.1

2 release files

1.0.0

2 release files

0.1.0

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page