Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Validate datetime value using python jsonschema

I'm using jsonschema to validate my python dictionary. I' trying to validate a datetime value but I'm not sure how to do it.

Here's what I have so far, which results in an error because jsonschema doesn't have a datetime type:

order = {
    "name": "shirt",
    "order_datetime": datetime.datetime(2018, 1, 18)
}

schema = {
    "title": "Order",
    "type": "object",
    "required": ["name", "order_datetime"],
    "properties": {
        "name": {
            "type": "string"
        },
        "order_datetime": {
            "type": "datetime"
        }
    }
}

from jsonschema import validate
validate(order, schema)

The error is jsonschema.exceptions.SchemaError: 'datetime' is not valid under any of the given schemas. How can I validate this correctly?

like image 823
Johnny Metz Avatar asked Sep 06 '18 18:09

Johnny Metz


2 Answers

Here's how to properly validate with a native Python datetime object. Assumes you have jsonschema 3.x:

from datetime import datetime
import jsonschema

def validate_with_datetime(schema, instance):
  BaseVal = jsonschema.Draft7Validator

  # Build a new type checker
  def is_datetime(checker, inst):
    return isinstance(inst, datetime)
  date_check = BaseVal.TYPE_CHECKER.redefine('datetime', is_datetime)

  # Build a validator with the new type checker
  Validator = jsonschema.validators.extend(BaseVal, type_checker=date_check)

  # Run the new Validator
  Validator(schema=schema).validate(instance)
like image 138
speedplane Avatar answered Sep 18 '22 12:09

speedplane


Once you add rfc3339-validator or strict-rfc3339 to project dependencies (the first one is much more accurate as I can see), jsonschema.FormatChecker class will register the date-time format validator. So the code will be as simple, as it should be:

from jsonschema import (
    Draft7Validator,
    FormatChecker,
)

schema = {
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "datetime": {
      "type": "string",
      "format": "date-time"
    }
  }
}

validator = Draft7Validator(schema, format_checker=FormatChecker())
data_samples = [
    {'datetime': '2021-01-01T00:01:02.003+01:00'},
    {'datetime': '2021-01-01'},
]
assert validator.is_valid(data_samples[0]) is True
assert validator.is_valid(data_samples[1]) is False

You can have a look at other possible to use formats, libraries they require, and other tips at jsonschema documentation page.

like image 27
Golikov Ivan Avatar answered Sep 20 '22 12:09

Golikov Ivan