This repository was originally developed by Harold Solbrig and was kindly contributed to the LinkML organization because of his retirement. All credit for the original development of this repository goes to him.
PyJSG -- JSON Schema Grammar Bindings for Python
Translate JSON Schema Grammar into Python objects.
This tool generates Python 3 objects that represent the JSON objects defined in a JSG schema. It uses the Python Typing library to add type hints to Python IDE's and includes a library to validate the python objects against the library definitions.
Examples
| JSON Grammar | Python Objects | |
|---|---|---|
doc { status:"ready" } |
class _Anon1(jsg.JSGString):
pattern = jsg.JSGPattern(r'ready') | |
doc { street:@string no:@int }
| class doc(jsg.JSGObject):
def __init__(self,
street: str = None,
no: int = None,
**_kwargs: Dict[str, object]):
self.street = jsg.String(street)
self.no = jsg.Integer(no)
super().__init__(self._context, **_kwargs)
| |
doc { street:(NAME|"*"|TEMPLATE) } | class _Anon1(jsg.JSGString):
pattern = jsg.JSGPattern(r'\*') | |
doc { street:nameOrTemplate }
nameOrTemplate = (NAME | TEMPLATE) ; | class NAME(jsg.JSGString):
pattern = jsg.JSGPattern(r'.*') | |
doc { street:[(NAME | "*" | TEMPLATE){2,}] }
@terminals
NAME : .*;
TEMPLATE : '{' .* '}'; | class _Anon1(jsg.JSGString):
pattern = jsg.JSGPattern(r'\*') |
Usage
- Requires Python 3.x -- has been tested through Python 3.6.1. (This module depends on some of the internal features of the Python typing library, which is still under active development -- be careful upgrading to newer versions without first running the unit tests.)
> pip install pyjsg
> generate_parser -h
usage: generate_parser [-h] [-o OUTFILE] [-e] infile
positional arguments:
infile Input JSG specification
optional arguments:
-h, --help show this help message and exit
-o OUTFILE, --outfile OUTFILE
Output python file (Default: {infile}.jsg)
-e, --evaluate Evaluate resulting python file as a test
Setup
> curl https://raw.githubusercontent.com/hsolbrig/shexTest/master/doc/ShExJ.jsg -o ShExJ.jsg
> generate_parser ShExJ.jsg
Output written to ShExJ.py
Python
from tests.py import ShExJ
from pyjsg.jsglib.jsg import loads
from io import StringIO
# Load an exsting schema
shexj = """{
"@context": "http://www.w3.org/ns/shex.jsonld",
"type": "Schema",
"shapes": [
{
"id": "http://a.example/S1",
"type": "Shape",
"expression": {
"type": "TripleConstraint",
"predicate": "http://a.example/p1",
"valueExpr": {
"type": "NodeConstraint",
"datatype": "http://a.example/dt1"
}
}
}
]
}
"""
s: ShExJ.Schema = loads(shexj, ShExJ)
print(f"type(Schema) = {s.type}")
print(f"PREDICATE: {s.shapes[0].expression.predicate}")
# Add a new element
s.shapes[0].closed = Boolean("true")
# Emit modified JSON
print(s._as_json_dumps())
# Validate the JSON
print(f"Valid: {s._is_valid()")
# Add an invalid element that isn't caught
s.shapes[0].expression.valueExpr = "Just text"
log = StringIO()
if not s._is_valid(log):
print(log.getvalue())
# Attempt to add in invalid string
try:
s.shapes[0].closed = Boolean("0", True)
except ValueError:
print("String mismatch")
# Attempt to add in invalid property
try:
s.shapes[0].closd = Boolean("true")
except ValueError:
print("No attribute named 'closd'")
Output
type(Shema): Schema
PREDICATE: http://a.example/p1
{
"type": "Schema",
"@context": "http://www.w3.org/ns/shex.jsonld",
"shapes": [
{
"type": "Shape",
"id": "http://a.example/S1",
"closed": "true",
"expression": {
"type": "TripleConstraint",
"predicate": "http://a.example/p1",
"valueExpr": {
"type": "NodeConstraint",
"datatype": "http://a.example/dt1"
}
}
}
]
}
Valid: True
String mismatch
No attribute named 'closd'
Release files for PyJSG 0.12.4
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pyjsg-0.12.4.tar.gz | 149.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pyjsg-0.12.4-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 231.6 kB
Release files / pyjsg-0.12.4.tar.gz
| Download URL | pyjsg-0.12.4.tar.gz |
|---|---|
| Size | 149.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
bb1c0ff1f50846d2b5185b182e28b0b6978eae51a2078ce3eb1e0f28dea7b9ab
|
|
BLAKE2b-256 checksum How to use checksums |
c44e192169ba1066454f016927fc46c7e595a6c701fd1173bd249efcf6de40b3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.13
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 1, 2026.
Transparency logRelease files / pyjsg-0.12.4-py3-none-any.whl
| Download URL | pyjsg-0.12.4-py3-none-any.whl |
|---|---|
| Size | 81.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a57ae58bfd7192b32654a0024bc6462fb459d54e837f0b2b5cff0726aad2e557
|
|
BLAKE2b-256 checksum How to use checksums |
0905d129d016f5124adb882816bdaef44bb877e313ceb0a109abcf553f1ac90c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.13
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 1, 2026.
Transparency log