Skip to main content

Python JSON Schema Grammar interpreter

Reason this release was yanked:

requests is only part of dev dependencies

Project description

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.

Pyversions PyPi Build Publish

Examples

JSON GrammarPython Objects
doc { status:"ready" }
class _Anon1(jsg.JSGString):
    pattern = jsg.JSGPattern(r'ready')
class doc(jsg.JSGObject): def __init__(self, status: _Anon1 = None, **_kwargs: Dict[str, object]): self.status = status super().__init__(self._context, **_kwargs)
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) }
@terminals NAME : [A-Za-z].*; TEMPLATE : '{' .* '}';
class _Anon1(jsg.JSGString):
    pattern = jsg.JSGPattern(r'\*')
class NAME(jsg.JSGString): pattern = jsg.JSGPattern(r'[A-Za-z].*')
class TEMPLATE(jsg.JSGString): pattern = jsg.JSGPattern(r'\{.*\}')
class doc(jsg.JSGObject): def __init__(self, street: Union[_Anon1, NAME, TEMPLATE] = None, **_kwargs: Dict[str, object]): self.street = street super().__init__(self._context, **_kwargs)
doc { street:nameOrTemplate }
nameOrTemplate = (NAME | TEMPLATE) ;
@terminals NAME : .*; TEMPLATE : '{' .* '}';
class NAME(jsg.JSGString):
    pattern = jsg.JSGPattern(r'.*')
class TEMPLATE(jsg.JSGString): pattern = jsg.JSGPattern(r'\{.*\}')
nameOrTemplate = Union[NAME, TEMPLATE]
class doc(jsg.JSGObject): def __init__(self, street: nameOrTemplate = None, **_kwargs: Dict[str, object]): self.street = street super().__init__(self._context, **_kwargs)
doc { street:[(NAME | "*" | TEMPLATE){2,}] }
@terminals
NAME : .*;
TEMPLATE : '{' .* '}';
class _Anon1(jsg.JSGString):
    pattern = jsg.JSGPattern(r'\*')
class NAME(jsg.JSGString): pattern = jsg.JSGPattern(r'.*')
class TEMPLATE(jsg.JSGString): pattern = jsg.JSGPattern(r'\{.*\}')
class doc(jsg.JSGObject): def __init__(self, street: List[Union[_Anon1, NAME, TEMPLATE]] = None, **_kwargs: Dict[str, object]): self.street = street super().__init__(self._context, **_kwargs)

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'

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

pyjsg-0.12.2.tar.gz (137.6 kB view details)

Uploaded Source

Built Distribution

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

pyjsg-0.12.2-py3-none-any.whl (81.7 kB view details)

Uploaded Python 3

File details

Details for the file pyjsg-0.12.2.tar.gz.

File metadata

  • Download URL: pyjsg-0.12.2.tar.gz
  • Upload date:
  • Size: 137.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.8.20

File hashes

Hashes for pyjsg-0.12.2.tar.gz
Algorithm Hash digest
SHA256 a6cd945b63f916c0a3d6bf6102df1c7de4e9bc1612ebae1025faf42afff2e5c3
MD5 eb4492d1c8a1c26c10bafa9b617561f3
BLAKE2b-256 80d1337627c3cf9b94eb6d3ba1b29aa62d6cd9e0944a0dab917543151571ad14

See more details on using hashes here.

File details

Details for the file pyjsg-0.12.2-py3-none-any.whl.

File metadata

  • Download URL: pyjsg-0.12.2-py3-none-any.whl
  • Upload date:
  • Size: 81.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.8.20

File hashes

Hashes for pyjsg-0.12.2-py3-none-any.whl
Algorithm Hash digest
SHA256 937dd783cacc55f6afa66dd8607a6c546fc99ce433cce6abe87096f76be425fa
MD5 8d12de977f48305f6f0186aa56c2fdcb
BLAKE2b-256 b0345d36f4d0e9c1a54e38a4c0c2734a516ed2d5f022111a642cf5d9f65b03f2

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