validate_helper.py 3.23 KB
Newer Older
1 2 3
#!/usr/bin/env python3
""" Call validation code """

4
import logging
5 6 7

import requests

Pierre Dittgen's avatar
Pierre Dittgen committed
8 9 10 11 12
from validata_validate import validate

#
# MEMENTO: json.load(pkg_resources.resource_stream('validata_validate', 'spec.json'))
#
Pierre Dittgen's avatar
Pierre Dittgen committed
13 14

log = logging.getLogger(__name__)
15 16 17 18 19 20 21 22


class ValidatorHelper:
    """ Help validating tabular data """

    schema_dict = {}

    @classmethod
Christophe Benz's avatar
Christophe Benz committed
23
    def init(cls, schema_info):
24 25 26
        """ Register and download schema and custom_checks info """
        cls.schema_dict = {}
        for code in schema_info:
Pierre Dittgen's avatar
Pierre Dittgen committed
27
            log.info('Downloading schema %s', code)
28 29 30 31 32 33 34
            schema = schema_info[code].copy()

            # schema download
            schema['schema'] = cls.json_download(schema['schema_json_url'],
                                                 '{}_schema.json'.format(code))

            # custom_checks
35 36 37
            if 'goodtables_checks_json_url' in schema:
                schema['goodtables_checks'] = cls.json_download(schema['goodtables_checks_json_url'],
                                                                '{}_goodtables_checks.json'.format(code))
38 39 40 41 42
            cls.schema_dict[code] = schema

    @classmethod
    def json_download(cls, url, filename):
        """ Download url content as JSON """
Christophe Benz's avatar
Christophe Benz committed
43
        return requests.get(url).json()
44 45 46 47 48 49 50 51 52 53 54

    @classmethod
    def schema_exist(cls, schema_code):
        """ Checks if schema exists """
        return schema_code in cls.schema_dict

    @classmethod
    def schema_info(cls, schema_code):
        """ Return schema info from code """
        if not cls.schema_exist(schema_code):
            return None
Pierre Dittgen's avatar
Pierre Dittgen committed
55 56 57 58 59 60

        # First schema keys but 'fields'
        d1 = dict([(k, v) for k, v in cls.schema_dict[schema_code]['schema'].items() if k != 'fields'])

        # All keys but schema* and custom_checks*
        d2 = {k: v for k, v in cls.schema_dict[schema_code].items()
61
              if not k.startswith('schema') and not k.startswith('goodtables_checks')}
Pierre Dittgen's avatar
Pierre Dittgen committed
62 63

        return {**d1, 'code': schema_code, **d2}
64

Pierre Dittgen's avatar
Pierre Dittgen committed
65
    @classmethod
66 67
    def schema(cls, schema_code):
        """ Return schema from schema code """
Pierre Dittgen's avatar
Pierre Dittgen committed
68 69
        if not cls.schema_exist(schema_code):
            return None
70
        return cls.schema_dict[schema_code]['schema']
Pierre Dittgen's avatar
Pierre Dittgen committed
71

72 73 74 75 76 77
    @classmethod
    def schema_info_list(cls):
        """ Computes and return schema info list """
        return [cls.schema_info(code) for code in sorted(cls.schema_dict.keys())]

    @classmethod
78
    def validate(cls, schema_code, **args):
Pierre Dittgen's avatar
Pierre Dittgen committed
79 80 81 82 83 84 85
        """ Validate source against schema using custom-checks """

        # Gets schema info
        sc_info = cls.schema_dict[schema_code]

        # Build checks configuration
        checks = ['structure', 'schema']
86
        pre_checks_conf = None
87 88
        if 'goodtables_checks' in sc_info:
            c_checks = sc_info['goodtables_checks']
89 90 91 92
            if 'custom_checks' in c_checks:
                for check_conf in c_checks['custom_checks']:
                    checks.append({check_conf['name']: check_conf['params']})
            pre_checks_conf = c_checks.get('pre_checks')
Pierre Dittgen's avatar
Pierre Dittgen committed
93 94

        return validate(
95
            source=args['source'],
Pierre Dittgen's avatar
Pierre Dittgen committed
96
            schema=sc_info['schema'],
Pierre Dittgen's avatar
Pierre Dittgen committed
97
            pre_checks_conf=pre_checks_conf,
98
            checks=checks,
99
            **{k: v for k, v in args.items() if k != 'source'}
Pierre Dittgen's avatar
Pierre Dittgen committed
100
        )