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.
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'\*') |
- 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
> curl https://raw.githubusercontent.com/hsolbrig/shexTest/master/doc/ShExJ.jsg -o ShExJ.jsg
> generate_parser ShExJ.jsg
Output written to ShExJ.py
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'")
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'