How to set up local file references in python-jsonschema document?

后端 未结 5 1941
失恋的感觉
失恋的感觉 2021-01-02 08:28

I have a set of jsonschema compliant documents. Some documents contain references to other documents (via the $ref attribute). I do not wish to host these docum

5条回答
  •  挽巷
    挽巷 (楼主)
    2021-01-02 09:18

    EDIT

    Fixed a wrong reference ($ref) to base schema. Updated the example to use the one from the docs: https://json-schema.org/understanding-json-schema/structuring.html

    This is just another version of @Daniel's answer -- which was the one correct for me. Basically, I decided to define the $schema in a base schema. Which then release the other schemas and makes for a clear call when instantiating the resolver.

    • The fact that RefResolver.from_schema() gets (1) some schema and also (2) a schema-store was not very clear to me whether the order and which "some" schema were relevant here. And so the structure you see below.

    I have the following:

    base.schema.json:

    {
      "$schema": "http://json-schema.org/draft-07/schema#"
    }
    

    definitions.schema.json:

    {
      "type": "object",
      "properties": {
        "street_address": { "type": "string" },
        "city":           { "type": "string" },
        "state":          { "type": "string" }
      },
      "required": ["street_address", "city", "state"]
    }
    

    address.schema.json:

    {
      "type": "object",
    
      "properties": {
        "billing_address": { "$ref": "definitions.schema.json#" },
        "shipping_address": { "$ref": "definitions.schema.json#" }
      }
    }
    

    I like this setup for two reasons:

    1. Is a cleaner call on RefResolver.from_schema():

      base = json.loads(open('base.schema.json').read())
      definitions = json.loads(open('definitions.schema.json').read())
      schema = json.loads(open('address.schema.json').read())
      
      schema_store = {
        base.get('$id','base.schema.json') : base,
        definitions.get('$id','definitions.schema.json') : definitions,
        schema.get('$id','address.schema.json') : schema,
      }
      
      resolver = RefResolver.from_schema(base, store=schema_store)
      
    2. Then I profit from the handy tool the library provides give you the best validator_for your schema (according to your $schema key):

      Validator = validator_for(base)
      
    3. And then just put them together to instantiate validator:

      validator = Validator(schema, resolver=resolver)
      

    Finally, you validate your data:

    data = {
      "shipping_address": {
        "street_address": "1600 Pennsylvania Avenue NW",
        "city": "Washington",
        "state": "DC"   
      },
      "billing_address": {
        "street_address": "1st Street SE",
        "city": "Washington",
        "state": 32
      }
    }
    
    • This one will crash since "state": 32:
    >>> validator.validate(data)
    
    ValidationError: 32 is not of type 'string'
    
    Failed validating 'type' in schema['properties']['billing_address']['properties']['state']:
        {'type': 'string'}
    
    On instance['billing_address']['state']:
        32
    

    Change that to "DC", and will validate.

提交回复
热议问题