#!/usr/bin/env python3 from cerberus import Validator from schwifty import IBAN, BIC import datetime def valid_iban(field, value, error): try: IBAN(value) return True except ValueError: error(field, 'not a valid IBAN') def valid_bic(field, value, error): try: BIC(value) return True except ValueError: error(field, 'not a valid BIC') def iso_date(field, value, error): try: datetime.datetime.strptime(value, "%Y-%m-%d") return True except ValueError: error(field, 'not a valid ISO 8601 date') def valid_money_amount(field, value, error): try: float(value) return True except (ValueError, TypeError): error(field, 'not a valid money value') document = { 'finanzdaten': { 'bic': 'PBNKDEFFXXX', 'holder': '', 'iban': 'DE89370400440532013000', 'issuance': '2012-01-01', 'reference': '0042', 'scan-sepa-mandate': '' }, 'mitgliederdaten': { 'bis': '', 'mitgliedsbeitrag': '30', 'scan-antrag': '', 'schliessberechtigung': 'Ja', 'spendenbeitrag': '0', 'status': 'V', 'von': '2012-01-01' }, 'stammdaten': { 'address_code': '39104', 'address_country': 'DE', 'address_label': 'Max Hackerberg\nLeibnizstr. 32\n39104 Magdeburg', 'address_locality': 'Magdeburg', 'address_region': '', 'address_street': 'Leibnizstr. 32', 'birth_date': '1970-01-01', 'birth_location': 'Hackstadt', 'email': 'max.hackerberg@netz39.de', 'fullname': 'Max Hackerberg', 'nickname': 'maxH', 'pgp-key': '', 'ssh-key': '' }, 'timestamp': '2020-03-25T23:58:11', 'id': '6af68' } schema_fin={ 'bic': { 'type': 'string', 'required': True, 'check_with': valid_bic}, 'iban': { 'type': 'string', 'required': True, 'check_with': valid_iban}, 'issuance': { 'type': 'string', 'required': True, 'check_with': iso_date}, 'reference': {'type': 'string'}, 'scan-sepa-mandate': {'type': 'string'}, 'holder': {'type': 'string'}} schema_membership={ 'bis': { 'type': 'string', 'oneof': [{'check_with': iso_date},{'empty': True}]}, 'mitgliedsbeitrag': { 'type': 'string', 'check_with': valid_money_amount}, 'scan-antrag': {'type': 'string'}, 'schliessberechtigung': { 'type': 'string', 'allowed': ['Ja', 'Nein', 'J', 'N', 'j', 'n', 'y', 'Y']}, 'spendenbeitrag': { 'type': 'string', 'check_with': valid_money_amount}, 'status': { 'type': 'string', 'allowed': ['V', 'E', 'F']}, 'von': { 'type': 'string', 'required': True, 'check_with': iso_date}} schema_base={ 'address_code': { 'type': 'string'}, 'address_country': { 'type': 'string'}, 'address_label': { 'type': 'string'}, 'address_locality': { 'type': 'string'}, 'address_region': { 'type': 'string'}, 'address_street': { 'type': 'string'}, 'birth_date': { 'type': 'string', 'required': True, 'check_with': iso_date}, 'birth_location': { 'type': 'string'}, 'email': { 'type': 'string', 'regex': '^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$'}, 'fullname': { 'type': 'string'}, 'nickname': { 'type': 'string'}, 'pgp-key': { 'type': 'string'}, 'ssh-key': { 'type': 'string'}} schema = { 'finanzdaten': { 'type': 'dict', 'schema': schema_fin}, 'mitgliederdaten': { 'type': 'dict', 'schema': schema_membership}, 'stammdaten': { 'type': 'dict', 'schema': schema_base}, 'id': { 'type': 'string', 'regex': '^[a-f0-9]{5}$'}, 'timestamp': { 'type': 'string'} } v = Validator() print(v.validate(document, schema)) print(v.errors)