CerberusはPython用の軽量で拡張可能なデータ検証ライブラリです。

Cerberus is a lightweight and extensible data validation library for Python.

pypiより

公式のValidationのルールのドキュメントは以下のURLです:

簡単な使い方を以下で紹介します.

Install

$ pip install Cerberus

Example

最初の例

from cerberus import Validator

schema = {'name': {'type': 'string'}}
v = Validator(schema)

data = {'name': 'abc'}
print(v.validate(data))  # True
print(v.errors)  # {}

data = {'name': 1}
print(v.validate(data))  # False
print(v.errors)  # {'name': ['must be of string type']}

以下 validateのテスト用の関数を用意しておきます:

from cerberus import Validator


def show_validate(data, schema):
    v = Validator(schema)
    print(data)
    print(v.validate(data))
    print(v.errors)
    print('=' * 80)


schema = {'name': {'type': 'string'}}

show_validate({'name': 'abc'}, schema)
# {'name': 'abc'}
# True
# {}

show_validate({'name': 1}, schema)
# {'name': 1}
# False
# {'name': ['must be of string type']}

型としてはboolean, binary, date, datetime, dict, float, integer, list, number, set, string に対応しています.

詳しくはドキュメントのtypeの項目をご覧ください.

nameは必須項目として定義されていないので, nameがなくても 問題はありません:

show_validate({}, schema)
# {}
# True
# {}

過剰に項目があると validateは失敗します:

show_validate({'name': 'yassu', 'age': 12}, schema)
# {'name': 'yassu', 'age': 12}
# False
# {'age': ['unknown field']}

データの型が辞書ではない場合は Errorが発生します:

show_validate('abc', schema)
# cerberus.validator.DocumentError: 'abc' is not a document, must be a dict

必須の項目を定義する

schema = {
    'name': {
        'type': 'string',
        'required': True,
    }
}

show_validate({'name': 'yassu'}, schema)
# {'name': 'yassu'}
# True
# {}

show_validate({}, schema)
# {}
# False
# {'name': ['required field']}

過剰な項目を許容する

Validatorのコンストラクタにallow_unknown=Trueを与えると, 過剰な項目を許容することができます:

def show_validate(data, schema):
    v = Validator(schema, allow_unknown=True)
    print(data)
    print(v.validate(data))
    print(v.errors)
    print('=' * 80)


schema = {
    'name': {
        'type': 'string',
        'required': True,
    }
}

show_validate({'name': 'yassu', 'age': 12}, schema)
# {'name': 'yassu'}
# True
# {}

Noneを許容する

前までの例ではNoneは許容されません:

schema = {'name': {'type': 'string'}}

show_validate({'name': None}, schema)
# {'name': None}
# False
# {'name': ['null value not allowed']}

Noneを許容するには指定の項目にnullable: Trueを指定します:

schema = {
    'name': {
        'type': 'string',
        'nullable': True,
    }
}

show_validate({'name': None}, schema)
# {'name': None}
# True
# {}

Validationのルールを関数で指定する

nameの最初か最後に空白文字が含まれない, というバリデーションは以下のようにして書けます:

def validate_name(field: str, value: str, error: Callable[..., None]) -> None:
    if value != value.strip():
        error(field, 'has first or last space char')


schema = {'name': {'type': 'string', 'check_with': validate_name}}

show_validate({'name': 'yassu'}, schema)
{'name': 'yassu'}
True
{}

show_validate({'name': ' yassu'}, schema)
{'name': ' yassu'}
False
{'name': ['has first or last space char']}

辞書のkeyのルールを指定する

schema = {
    'ages': {
        'type': 'dict',
        'keysrules': {
            'type': 'string'
        },
    },
}

show_validate({'ages': {'yassu': 28}}, schema)
# {'ages': {'yassu': 28}}
# True
# {}

show_validate({'ages': {12: 28}}, schema)
# {'ages': {12: 28}}
# False
# {'ages': [{12: ['must be of string type']}]}

辞書のvalueのルールを指定する

schema = {
    'ages': {
        'type': 'dict',
        'valuesrules': {
            'type': 'integer'
        },
    },
}

show_validate({'ages': {'yassu': 28}}, schema)
# {'ages': {'yassu': 28}}
# True
# {}

show_validate({'ages': {'yassu': '28'}}, schema)
# {'ages': {'yassu': '28'}}
# False
# {'ages': [{'yassu': ['must be of integer type']}]}

ネストした項目のルールを指定する

schema = {
    'info': {
        'schema': {
            'name': {
                'type': 'string'
            },
            'gender': {
                'type': 'string'
            },
        },
    }
}

data = {
    'info': {
        'name': 'yassu',
        'gender': 'male',
    }
}

show_validate(data, schema)
# {'info': {'name': 'yassu', 'gender': 'male'}}
# True
# {}

data = {
    'info': {
        'name': 'yassu',
        'gender': 0,
    }
}
show_validate(data, schema)
# {'info': {'name': 'yassu', 'gender': 0}}
# False
# {'info': [{'gender': ['must be of string type']}]}