Skip to content

Commit 734ef3a

Browse files
committed
improve validator output, make usage more consistent with skinfer
1 parent bca630b commit 734ef3a

File tree

3 files changed

+49
-43
lines changed

3 files changed

+49
-43
lines changed

bin/json_validator

+41-35
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,66 @@
11
#!/usr/bin/env python
22
# coding=utf-8
3+
"""Validates a json file against a given json schema
4+
"""
5+
36

47
import argparse
58
import json
69

7-
from jsonschema import validate, Draft4Validator
10+
from jsonschema import validate, Draft4Validator, ValidationError
11+
from skinfer import schema_inferer
812

913

1014
def parse_args():
11-
desc = 'Validates a json file against a given json schema.'
12-
parser = argparse.ArgumentParser(description=desc)
13-
parser.add_argument('json_schema', type=str,
15+
parser = argparse.ArgumentParser(description=__doc__)
16+
parser.add_argument('json_schema',
1417
help='Path to the json schema file')
15-
parser.add_argument('json_file', type=str,
16-
help='Path to the json file')
18+
parser.add_argument('instances', nargs='+', metavar='INSTANCE',
19+
help='JSON data files to be validated')
20+
parser.add_argument('--jsonlines', action='store_true',
21+
help='Assume instances are in JSON lines format')
1722
return parser.parse_args()
1823

1924

20-
def read_json(json_file):
21-
try:
22-
with open(json_file) as f:
23-
if json_file.endswith('.json'):
24-
return json.load(f)
25-
elif json_file.endswith('.jl'):
26-
return [json.loads(s) for s in f.readlines()]
27-
except Exception as e:
28-
print('Invalid json: %s' % e.message)
29-
30-
31-
def read_schema(json_schema):
32-
with open(args.json_schema) as f:
33-
schema = json.load(f)
34-
35-
try:
36-
Draft4Validator.check_schema(schema)
37-
return schema
38-
except Exception as e:
39-
print('Invalid schema: %s' % e.message)
25+
def load_json(filepath):
26+
with open(filepath) as f:
27+
return json.load(f)
4028

4129

42-
def run(args):
43-
schema = read_schema(args.json_schema)
44-
json_data = read_json(args.json_file)
30+
def error_message(position, error):
31+
def convert(x):
32+
return '[%r]' % x
33+
field = ''.join(convert(x) for x in error.relative_path)
34+
return 'Failed validation for field %s in entry %d: %s' % (field, position, error.message)
4535

46-
if not schema or not json_data:
47-
return
4836

37+
def run_validation(schema, instances):
4938
errors = 0
50-
for line, item in enumerate(json_data, 1):
39+
total = 0
40+
for i, item in enumerate(instances, 1):
41+
total += 1
5142
try:
5243
validate(item, schema)
53-
except Exception as e:
44+
except ValidationError as e:
5445
errors += 1
55-
print('Error validating line %d: %s' % (line, e.message))
46+
print(error_message(i, e))
47+
48+
print("%d errors found in %d items validated" % (errors, total))
49+
5650

57-
print("%d items validated. %d errors." % (len(json_data), errors))
51+
def run(args):
52+
schema = load_json(args.json_schema)
53+
Draft4Validator.check_schema(schema)
54+
55+
try:
56+
instances = schema_inferer.load_samples(args.instances, args.jsonlines)
57+
run_validation(schema, instances)
58+
except ValueError as e:
59+
if 'Extra data:' in e.message:
60+
instances = schema_inferer.load_samples(args.instances, jsonlines=True)
61+
run_validation(schema, instances)
62+
else:
63+
raise
5864

5965

6066
if __name__ == '__main__':

bin/skinfer

+1-8
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,12 @@ import json
99
from skinfer import schema_inferer
1010

1111

12-
def get_samples(samples, jsonlines=False):
13-
if jsonlines:
14-
return schema_inferer.load_samples_from_jsonlines(samples)
15-
16-
return schema_inferer.load_samples_from_json(samples)
17-
18-
1912
def write_schema(schema):
2013
print(json.dumps(schema, indent=4))
2114

2215

2316
def try_infer_schema(args):
24-
samples = get_samples(args.samples, args.jsonlines)
17+
samples = schema_inferer.load_samples(args.samples, args.jsonlines)
2518
return schema_inferer.generate_and_merge_schemas(samples)
2619

2720

skinfer/schema_inferer.py

+7
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,13 @@ def load_samples_from_json(file_list):
2626
yield json.load(f)
2727

2828

29+
def load_samples(samples, jsonlines=False):
30+
if jsonlines:
31+
return load_samples_from_jsonlines(samples)
32+
33+
return load_samples_from_json(samples)
34+
35+
2936
def generate_schema_for_sample(sample):
3037
"""Returns a schema generated for the given sample.
3138
"""

0 commit comments

Comments
 (0)