import json import collections class ParsedItem(dict): """ Parsed Schema item """ def __init__(self, json_object, name, required, level): """Fills dict with basic item information""" super(ParsedItem, self).__init__() self['name'] = name self['title'] = json_object.get('title', '') self['type'] = json_object.get('type') self['description'] = json_object.get('description', '') self['level'] = level self['required'] = required self['x-reference'] = json_object.get('x-reference', '') self['x-example'] = json_object.get('x-example', '') self['pattern'] = json_object.get('pattern', '') self['enum'] = json_object.get('enum', '') class DocsModel: """ Documentation model and Schema Parser """ def __init__(self): self.__parsed_items = None def parse(self, json_object): """ Returns multi-level list of recursively parsed items """ self.__parsed_items = list() self.__parse_schema(json_object, 'root', True, 0) return self.__parsed_items def __parse_schema(self, schema, name, required, level): """ Parses schema, which type is object, array or leaf. Appends new ParsedItem to self.__parsed_items lis """ parsed_item = ParsedItem(schema, name, required, level) self.__parsed_items.append(parsed_item) required = schema.get('required', []) if 'enum' in schema: parsed_item['item'] = schema.get('enum') item_type = schema.get('type') if item_type == 'object' and name != 'DISTRIBUTED_STORAGE_CONFIG': self.__parse_object(parsed_item, schema, required, level) elif item_type == 'array': self.__parse_array(parsed_item, schema, required, level) else: parse_leaf(parsed_item, schema) def __parse_object(self, parsed_item, schema, required, level): """ Parses schema of type object """ for key, value in schema.get('properties', {}).items(): self.__parse_schema(value, key, key in required, level + 1) def __parse_array(self, parsed_item, schema, required, level): """ Parses schema of type array """ items = schema.get('items') parsed_item['minItems'] = schema.get('minItems', None) parsed_item['maxItems'] = schema.get('maxItems', None) parsed_item['uniqueItems'] = schema.get('uniqueItems', False) if isinstance(items, dict): # item is single schema describing all elements in an array self.__parse_schema( items, 'array item', required, level + 1) elif isinstance(items, list): # item is a list of schemas for index, list_item in enumerate(items): self.__parse_schema( list_item, 'array item {}'.format(index), index in required, level + 1) def parse_leaf(parsed_item, schema): """ Parses schema of a number and a string """ if parsed_item['name'] != 'root': parsed_item['description'] = schema.get('description','') parsed_item['x-reference'] = schema.get('x-reference','') parsed_item['pattern'] = schema.get('pattern','') parsed_item['enum'] = ", ".join(schema.get('enum','')).encode() ex = schema.get('x-example', '') if isinstance(ex, list): parsed_item['x-example'] = ", ".join(ex).encode() elif isinstance(ex, collections.OrderedDict): parsed_item['x-example'] = json.dumps(ex) else: parsed_item['x-example'] = ex