import collections import json 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