Проверьте значение даты и времени с помощью Python jsonschema

Я использую jsonschema для проверки моего словаря Python. Я пытаюсь подтвердить datetime ценность, но я не уверен, как это сделать.

Вот что у меня есть, что приводит к ошибке, потому что у jsonschema нет datetime тип:

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)

Ошибка jsonschema.exceptions.SchemaError: 'datetime' is not valid under any of the given schemas, Как я могу проверить это правильно?

5 ответов

Вот как правильно выполнить проверку с помощью собственного Python datetimeобъект. Предполагается, что у вас есть 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)

Как только вы добавите rfc3339-validator или же strict-rfc3339 для проектирования зависимостей (первый, как я вижу, гораздо точнее), jsonschema.FormatChecker класс зарегистрирует date-timeвалидатор формата. Так что код будет таким простым, каким должен быть:

      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

Вы можете ознакомиться с другими возможными форматами использования, необходимыми библиотеками и другими советами на странице документации jsonschema .

С помощью ответа @speedplane я смог заставить проверку типов работать для моего случая order_datetime.

order = {
    "name": "shirt",
    "order_datetime": "2019-09-13-22.30.00.000000"
}

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

Код Python

import jsonschema
def validate_with_datetime(schema, instance):
  BaseVal = jsonschema.Draft7Validator
  # Build a new type checker
  def is_datetime(checker, inst):
     try:
        datetime.datetime.strptime(inst, '%Y-%m-%d-%H.%M.%S.%f')
        return True
     except ValueError:
        return False
  date_check = BaseVal.TYPE_CHECKER.redefine(u'orderdatetime', 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)

validate_with_datetime(schema, order)

Но во время изучения библиотеки jsonschema я наткнулся на FormatChecker(). Разве мы не можем использовать jsonschema.FormatChecker() для проверки формата свойства типа datetime?

@speedplane Можете ли вы опубликовать пример использования FormatChecker()?

Просто передайте значение даты и времени как str .

      schema={"type":'object',
        "required":['date'],
        "properties":{"date":{'type':'string',format:'date-time'}}})

validate({'date':str(datetime.datetime(2023, 7, 27, 10, 33, 26, 569990))},schema)

Вы можете использовать встроенный __str__ метод datetime.datetimeэто преобразует его в строку, которая должна работать с JSON:

dt_string = str(datetime.datetime(2018, 1, 18))

order = {
    "name": "shirt",
    "order_datetime": dt_string
}

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

from jsonschema import validate
validate(order, schema)
Другие вопросы по тегам