Skip to content

Commit

Permalink
wip #24 schema検討中
Browse files Browse the repository at this point in the history
  • Loading branch information
setminami committed Jan 27, 2018
1 parent d6d0940 commit c584c9b
Show file tree
Hide file tree
Showing 6 changed files with 228 additions and 13 deletions.
27 changes: 19 additions & 8 deletions jsonica/schema_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,21 @@ class TypeSign(str, enum.Enum):
JSON_NULL = 'null'

class Schema:
""" abstract """
"""
抽象的な中継クラス
下流具象クラスへの中継とreduce以外の作業はさせないこと
"""

DEBUG = False
class JsonSchema:
""" concrete 1 as jsonschema style """
def __init__(self):
self.__schemas = []

def _makeSchema(self, type_desc):
"""
最小粒度でのjsonschema構築
"""
schema = {'type':'object'}
if 'required' in type_desc[1].keys():
schema['required'] = [type_desc[0]]
Expand All @@ -44,27 +51,31 @@ def _validate(self, evl, schema):
validate(evl, schema)
except ValidationError as ve:
self.__print('Validation Error has found.\n%s'%ve)
print('_validate {} with: {}'.format(evl, self.__schemas))
sys.exit(-1)
except SchemaError as se:
self.__print('Schema Error has found.\n%s'%se)
print('Error Schema : %s'%self.__schemas)
sys.exit(-2)

def __print(self, _str, flag=False):
if flag: print(_str)

def __init__(self, validator):
self.schema_name = validator
self.schema_collection = []
# TEMP: type switch
if validator == Validator.jsonschema:
self.schema = Schema.JsonSchema()

def makeSchema(self, desc):
""" 一項目ずつの定義であることに留意 """
Hoare.P(isinstance(desc[0], str) and isinstance(desc[1], dict))
# HACK: failfastとして小粒度で都度Errorを上げるか、reduceしたあと最後にvalidationをかけるか
return self.schema._makeSchema(desc)
# TEMP: failfastとして小粒度で都度Errorを上げるか、reduceしたあと最後にvalidationをかけるか
self.schema_collection.append(self.schema._makeSchema(desc))
return self.schema_collection[-1]

def validate(self, evl, desc):
sc = self.makeSchema(desc)
Hoare.P(isinstance(evl, list) or isinstance(evl, dict))
self.schema._validate(evl, sc)

def __print(self, _str, flag=False):
if flag: print(_str)
self.schema._validate(evl, self.makeSchema(desc))
# print('i\'m {} \nNow I have -> {}'.format(self, self.schema_collection))
7 changes: 7 additions & 0 deletions jsonica/sub_command_core/generate.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ def __run__(self, **kwargs):
errorout(6, args.output)
else:
self.__print('Output json Success ➡️ %s'%args.output)
# print('XXX %s XXX'%x.piled_schema)

def makeArgparse(self, subparser):
myparser = super().makeArgparse(subparser)
Expand All @@ -64,6 +65,12 @@ def makeArgparse(self, subparser):
nargs='?', type=str, default='root', # Default root sheet name
metavar='sheetname',
help='set a sheetname in xlsx book have. \nconstruct json tree from the sheet as root item. "root" is Default root sheet name.')
# reserve
# myparser.add_argument('-s', '--schema',
# nargs='?', type=str,
# metavar='schema url',
# help='http://json-schema.org/draft-04/schema#')

myparser.add_argument('-o', '--output',
nargs='?', type=str, action=AnalyzeJSONOutPath,
metavar='path/to/outputfile(.json)',
Expand Down
33 changes: 28 additions & 5 deletions jsonica/xlsx.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,31 @@ class XLSX:
""" xlsx 具象操作クラス """
# childへのリンクを示す接頭辞
sheet_link_sign = 'sheet://'
@property
def schema(self): return self.__schema
@schema.setter
def schema(self, value):
if not hasattr(self, '__schema'):
self.__schema = value

@property
def piled_schema(self):
"""
__all_schema: {sheet: [schemas]}
"""
return self.__all_schema
@piled_schema.setter
def piled_schema(self, value):
""" value : (sheet:Some, schema:dict) """
if value[0] in self.piled_schema.keys():
self.piled_schema[value[0]].update(value[1])
else:
self.piled_schema[value[0]] = value[1]

def __init__(self, file, enc, forms=None):
self.filepath = file
self.filename = os.path.basename(file)
self.__all_schema = {}
if forms:
self.format = forms[0]
self.format_delimiter = forms[1]
Expand Down Expand Up @@ -69,7 +90,7 @@ def generateJSON(self, sheet_name, acc=None):
else:
self.errorout(1, 'sheet = from %s to %s, col = %d, row = %d'%(sheet_name, link, j, i))
else:
XLSX.__store(self.typeValidator(v, columns[j]), accumulator=subacc)
XLSX.__store(self.typeValidator(sheet_name, v, columns[j]), accumulator=subacc)
# pass columns
Util.checkEmptyOr(lambda x: XLSX.__store(x, acc), subacc)
# pass a row
Expand Down Expand Up @@ -120,13 +141,15 @@ def checkCharEncode(self, item, valid_enc=None):
# TODO: excel rw 状態チェック
item.encoding = enc

def typeValidator(self, value, type_desc, validator=Validator.jsonschema):
def typeValidator(self, sheet_name, value, type_desc, validator=Validator.jsonschema):
""" Validator switch """
if not hasattr(self, '__schema'):
self.__schema = Schema(validator)
self.schema = Schema(validator)
raw = Util.convEscapedKV(XLSX.__getType(type_desc[1]), type_desc[0], value)
instance = Util.runtimeDictionary('{%s}'%raw)
self.__schema.validate(instance, type_desc)
self.__print('i\'m %s. call validator'%self, False)
self.__print('== %s =='%{type_desc[0]:type_desc[1]}, False)
self.piled_schema = (sheet_name, {type_desc[0]:type_desc[1]})
self.schema.validate(instance, type_desc)
Hoare.P(instance is not None)
return instance

Expand Down
62 changes: 62 additions & 0 deletions tests/data/jsonschema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
1 {
2 "$id": "http://example.com/example.json",
3 "type": "array",
4 "definitions": {},
5 "$schema": "http://json-schema.org/draft-06/schema#",
6 "items": {
7 "$id": "http://example.com/example.json/items",
8 "type": "object",
9 "properties": {
10 "color": {
11 "$id": "http://example.com/example.json/items/properties/color",
12 "type": "string",
13 "title": "The Color Schema",
14 "description": "An explanation about the purpose of this instance.",
15 "default": "",
16 "examples": [
17 "fff000"
18 ]
19 },
20 "items": {
21 "$id": "http://example.com/example.json/items/properties/items",
22 "type": "array",
23 "items": {
24 "$id": "http://example.com/example.json/items/properties/items/items",
25 "type": "object",
26 "properties": {
27 "desc-en": {
28 "$id": "http://example.com/example.json/items/properties/items/items/properties/desc-en",
29 "type": "string",
30 "title": "The Desc-en Schema",
31 "description": "An explanation about the purpose of this instance.",
32 "default": "",
33 "examples": [
34 "Matches at the start of string or start of line if multi-line mode is enabled. Many regex implementations have multi-line mode enabled by default."
35 ]
36 },
37 "sign": {
38 "$id": "http://example.com/example.json/items/properties/items/items/properties/sign",
39 "type": "string",
40 "title": "The Sign Schema",
41 "description": "An explanation about the purpose of this instance.",
42 "default": "",
43 "examples": [
44 "^"
45 ]
46 }
47 }
48 }
49 },
50 "title": {
51 "$id": "http://example.com/example.json/items/properties/title",
52 "type": "string",
53 "title": "The Title Schema",
54 "description": "An explanation about the purpose of this instance.",
55 "default": "",
56 "examples": [
57 "Anchors"
58 ]
59 }
60 }
61 }
62 }
63 changes: 63 additions & 0 deletions tests/data/jsonschema.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
1 <?xml version="1.0" ?>
2 <root>
3 <key name="$id">http://example.com/example.json</key>
4 <type>array</type>
5 <definitions/>
6 <key name="$schema">http://json-schema.org/draft-06/schema#</key>
7 <items>
8 <key name="$id">http://example.com/example.json/items</key>
9 <type>object</type>
10 <properties>
11 <color>
12 <key name="$id">http://example.com/example.json/items/properties/color</key>
13 <type>string</type>
14 <title>The Color Schema</title>
15 <description>An explanation about the purpose of this instance.</description>
16 <default/>
17 <examples>
18 <item>fff000</item>
19 </examples>
20 </color>
21 <items>
22 <key name="$id">http://example.com/example.json/items/properties/items</key>
23 <type>array</type>
24 <items>
25 <key name="$id">http://example.com/example.json/items/properties/items/items</key>
26 <type>object</type>
27 <properties>
28 <desc-en>
29 <key name="$id">http://example.com/example.json/items/properties/items/items/properties/desc-en</key>
30 <type>string</type>
31 <title>The Desc-en Schema</title>
32 <description>An explanation about the purpose of this instance.</description>
33 <default/>
34 <examples>
35 <item>Matches at the start of string or start of line if multi-line mode is enabled. Many regex implementations have multi-line mode enabled by default.</item>
36 </examples>
37 </desc-en>
38 <sign>
39 <key name="$id">http://example.com/example.json/items/properties/items/items/properties/sign</key>
40 <type>string</type>
41 <title>The Sign Schema</title>
42 <description>An explanation about the purpose of this instance.</description>
43 <default/>
44 <examples>
45 <item>^</item>
46 </examples>
47 </sign>
48 </properties>
49 </items>
50 </items>
51 <title>
52 <key name="$id">http://example.com/example.json/items/properties/title</key>
53 <type>string</type>
54 <title>The Title Schema</title>
55 <description>An explanation about the purpose of this instance.</description>
56 <default/>
57 <examples>
58 <item>Anchors</item>
59 </examples>
60 </title>
61 </properties>
62 </items>
63 </root>
49 changes: 49 additions & 0 deletions tests/data/jsonschema.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
1 $id: http://example.com/example.json
2 type: array
3 definitions: {}
4 $schema: http://json-schema.org/draft-06/schema#
5 items:
6 $id: http://example.com/example.json/items
7 type: object
8 properties:
9 color:
10 $id: http://example.com/example.json/items/properties/color
11 type: string
12 title: The Color Schema
13 description: An explanation about the purpose of this instance.
14 default: ''
15 examples:
16 - fff000
17 items:
18 $id: http://example.com/example.json/items/properties/items
19 type: array
20 items:
21 $id: http://example.com/example.json/items/properties/items/items
22 type: object
23 properties:
24 desc-en:
25 $id: http://example.com/example.json/items/properties/items/items/properties/desc-en
26 type: string
27 title: The Desc-en Schema
28 description: An explanation about the purpose of this instance.
29 default: ''
30 examples:
31 - Matches at the start of string or start of line if multi-line mode is
32 enabled. Many regex implementations have multi-line mode enabled by
33 default.
34 sign:
35 $id: http://example.com/example.json/items/properties/items/items/properties/sign
36 type: string
37 title: The Sign Schema
38 description: An explanation about the purpose of this instance.
39 default: ''
40 examples:
41 - ^
42 title:
43 $id: http://example.com/example.json/items/properties/title
44 type: string
45 title: The Title Schema
46 description: An explanation about the purpose of this instance.
47 default: ''
48 examples:
49 - Anchors

0 comments on commit c584c9b

Please sign in to comment.