使用正确的数据类型时,使用 Cerberus 验证 JSON 模式会引发错误

Validating JSON Schema with Cerberus throws error when using correct data type

我正在尝试验证 JSON 模式。当为 released 指定正确的数据类型 date 时,Cerberus 会抛出错误。

def test_validate_books_schema():
    schema = {
            "url" : {'type': 'string'},
            "name" : {'type': 'string'},
            "isbn" : {'type': 'string'},
            "authors" : {'type': ['string','list']},
            "numberOfPages" : {'type': 'integer'},
            "publisher" : {'type': 'string'},
            "country" : {'type': 'string'},
            "mediaType" : {'type': 'string'},
            "released" : {'type': 'date'},
            "characters" : {'type': ['string','list']},
            "povCharacters" : {'type': ['string','list']}            
        }

    response = requests.get("https://www.anapioficeandfire.com/api/books/1")
    
    v = Validator(schema)
    validate_response = v.validate(response.json())
    assert_that(validate_response, description=v.errors).is_true()
./tests/books/test_books.py::test_validate_books_schema Failed: [undefined]AssertionError: [{'released': ['must be of date type']}] Expected <True>, but was not.
def test_validate_books_schema():
        schema = {
                "url" : {'type': 'string'},
                "name" : {'type': 'string'},
                "isbn" : {'type': 'string'},
                "authors" : {'type': ['string','list']},
                "numberOfPages" : {'type': 'integer'},
                "publisher" : {'type': 'string'},
                "country" : {'type': 'string'},
                "mediaType" : {'type': 'string'},
                "released" : {'type': 'date'},
                "characters" : {'type': ['string','list']},
                "povCharacters" : {'type': ['string','list']}
            }
    
        response = requests.get("https://www.anapioficeandfire.com/api/books/1")
    
        v = Validator(schema)
        validate_response = v.validate(response.json())
>       assert_that(validate_response, description=v.errors).is_true()
E       AssertionError: [{'released': ['must be of date type']}] Expected <True>, but was not.

tests\books\test_books.py:42: AssertionError

documentation 表明 released 的数据类型是 Date。当我为 released 指定 string 时,它起作用了。

像这样稍微更改您的代码:

from cerberus import Validator
from assertpy import assert_that
from datetime import datetime
import requests

def date_hook(json_dict):
    for (key, value) in json_dict.items():
        try:
            json_dict[key] = datetime.strptime(value, "%Y-%m-%dT%H:%M:%S")
        except:
            pass
    return json_dict

def test_validate_books_schema():
    schema = {
            "url" : {'type': 'string'},
            "name" : {'type': 'string'},
            "isbn" : {'type': 'string'},
            "authors" : {'type': ['string','list']},
            "numberOfPages" : {'type': 'integer'},
            "publisher" : {'type': 'string'},
            "country" : {'type': 'string'},
            "mediaType" : {'type': 'string'},
            "released" : {'type': 'date'},
            "characters" : {'type': ['string','list']},
            "povCharacters" : {'type': ['string','list']}            
        }

    response = requests.get("https://www.anapioficeandfire.com/api/books/1")

    v = Validator(schema)
    validate_response = v.validate(response.json(object_hook=date_hook))
    assert_that(validate_response, description=v.errors).is_true()

test_validate_books_schema()
print('Done')

我们在这里所做的是在 response.json 中添加一个对象挂钩,它将调用 date_hook,它会适当地格式化 date/time (see this answer)

一旦你运行你的文件,你应该不会得到任何错误。