def _primative_to_document(data, base_url=None): """ Take Python primatives as returned from parsing JSON content, and return a Core API document. """ if isinstance(data, dict) and data.get('_type') == 'document': # Document meta = _get_dict(data, '_meta') url = _get_string(meta, 'url') url = urlparse.urljoin(base_url, url) title = _get_string(meta, 'title') content = _get_content(data, base_url=url) return Document(url=url, title=title, content=content) if isinstance(data, dict) and data.get('_type') == 'error': # Error meta = _get_dict(data, '_meta') title = _get_string(meta, 'title') content = _get_content(data, base_url=base_url) return Error(title=title, content=content) elif isinstance(data, dict) and data.get('_type') == 'link': # Link url = _get_string(data, 'url') url = urlparse.urljoin(base_url, url) action = _get_string(data, 'action') encoding = _get_string(data, 'encoding') transform = _get_string(data, 'transform') description = _get_string(data, 'description') fields = _get_list(data, 'fields') fields = [ Field(name=_get_string(item, 'name'), required=_get_bool(item, 'required'), location=_get_string(item, 'location'), type=_get_string(item, 'type'), description=_get_string(item, 'description')) for item in fields if isinstance(item, dict) ] return Link(url=url, action=action, encoding=encoding, transform=transform, description=description, fields=fields) elif isinstance(data, dict): # Map content = _get_content(data, base_url=base_url) return Object(content) elif isinstance(data, list): # Array content = [_primative_to_document(item, base_url) for item in data] return Array(content) # String, Integer, Number, Boolean, null. return data
def _primative_to_document(data, base_url=None): """ Take Python primatives as returned from parsing JSON content, and return a Core API document. """ if isinstance(data, dict) and data.get('_type') == 'document': # Document meta = _get_dict(data, '_meta') url = _get_string(meta, 'url') url = urlparse.urljoin(base_url, url) title = _get_string(meta, 'title') content = _get_content(data, base_url=url) return Document(url=url, title=title, content=content) if isinstance(data, dict) and data.get('_type') == 'error': # Error meta = _get_dict(data, '_meta') title = _get_string(meta, 'title') content = _get_content(data, base_url=base_url) return Error(title=title, content=content) elif isinstance(data, dict) and data.get('_type') == 'link': # Link url = _get_string(data, 'url') url = urlparse.urljoin(base_url, url) action = _get_string(data, 'action') encoding = _get_string(data, 'encoding') transform = _get_string(data, 'transform') description = _get_string(data, 'description') fields = _get_list(data, 'fields') fields = [ Field( name=_get_string(item, 'name'), required=_get_bool(item, 'required'), location=_get_string(item, 'location'), description=_get_string(item, 'description') ) for item in fields if isinstance(item, dict) ] return Link( url=url, action=action, encoding=encoding, transform=transform, description=description, fields=fields ) elif isinstance(data, dict): # Map content = _get_content(data, base_url=base_url) return Object(content) elif isinstance(data, list): # Array content = [_primative_to_document(item, base_url) for item in data] return Array(content) # String, Integer, Number, Boolean, null. return data
def _render_html(node, url=None, key=None, path=''): if key: path += "%s." % key if isinstance(node, (Document, Link)): url = urlparse.urljoin(url, node.url) if isinstance(node, Document): template = env.get_template('document.html') elif isinstance(node, Object): template = env.get_template('object.html') elif isinstance(node, Array): template = env.get_template('array.html') elif isinstance(node, Link): template = env.get_template('link.html') elif isinstance(node, Error): template = env.get_template('error.html') elif node is None or isinstance(node, bool): value = {True: 'true', False: 'false', None: 'null'}[node] return "<code>%s</code>" % value elif isinstance(node, (float, int)): return "<code>%s</code>" % node else: return "<span>%s</span>" % node.replace('\n', '<br/>') return template.render(node=node, render=_render_html, url=url, key=key, path=path)
def _parse_link(data, base_url=None): url = _get_string(data, 'href') url = urlparse.urljoin(base_url, url) if _get_bool(data, 'templated'): fields = [ Field(name, location='path') for name in uritemplate.variables(url) ] else: fields = None return Link(url=url, fields=fields)
def _parse_document(data, base_url=None): schema_url = base_url base_url = _get_document_base_url(data, base_url) info = _get_dict(data, 'info') title = _get_string(info, 'title') paths = _get_dict(data, 'paths') content = {} for path in paths.keys(): url = urlparse.urljoin(base_url, path.lstrip('/')) spec = _get_dict(paths, path) default_parameters = get_dicts(_get_list(spec, 'parameters')) for action in spec.keys(): action = action.lower() if action not in ('get', 'put', 'post', 'delete', 'options', 'head', 'patch'): continue operation = _get_dict(spec, action) # Determine any fields on the link. fields = [] parameters = get_dicts(_get_list(operation, 'parameters', default_parameters), dereference_using=data) for parameter in parameters: name = _get_string(parameter, 'name') location = _get_string(parameter, 'in') required = _get_bool(parameter, 'required', default=(location == 'path')) if location == 'body': schema = _get_dict(parameter, 'schema', dereference_using=data) expanded = _expand_schema(schema) if expanded is not None: expanded_fields = [ Field(name=field_name, location='form', required=is_required) for field_name, is_required in expanded if not any([field.name == name for field in fields]) ] fields += expanded_fields else: field = Field(name=name, location='body', required=True) fields.append(field) else: field = Field(name=name, location=location, required=required) fields.append(field) link = Link(url=url, action=action, fields=fields) # Add the link to the document content. tags = get_strings(_get_list(operation, 'tags')) operation_id = _get_string(operation, 'operationId') if tags: for tag in tags: if tag not in content: content[tag] = {} content[tag][operation_id] = link else: content[operation_id] = link return Document(url=schema_url, title=title, content=content)
def _get_content(data, base_url, ref): content = {} links = _get_list(data, 'links') properties = _get_dict(data, 'properties') if properties: for key, value in properties.items(): if not isinstance(value, dict): continue if list(value.keys()) == ['$ref']: value = _dereference(value['$ref'], ref) sub_content = _get_content(value, base_url, ref) if sub_content: content[key] = sub_content if links: for link in get_dicts(links): rel = _get_string(link, 'rel') if rel: href = _get_string(link, 'href') method = _get_string(link, 'method') schema = _get_dict(link, 'schema') schema_type = _get_list(schema, 'type') schema_properties = _get_dict(schema, 'properties') schema_required = _get_list(schema, 'required') fields = [] url = urlparse.urljoin(base_url, href) templated = uritemplate.variables(url) for item in templated: orig = item if item.startswith('(') and item.endswith(')'): item = unquote(item.strip('(').rstrip(')')) if item.startswith('#/'): components = [ component for component in item.strip('#/').split('/') if component != 'definitions' ] item = '_'.join(components).replace('-', '_') url = url.replace(orig, item) fields.append( Field(name=item, location='path', required=True)) if schema_type == ['object'] and schema_properties: fields += [ Field(name=key, required=(key in schema_required)) for key in schema_properties.keys() ] if rel == 'self': rel = 'read' content[rel] = Link(url=url, action=method, fields=fields) return content
def _yaml_include(self, loader, node): url = urlparse.urljoin(self.base_url, node.value) path = urlparse.urlparse(url).path ext = posixpath.splitext(path)[1] response = requests.get(url) if ext in [".yaml", ".yml", ".raml"]: return yaml.load(response.content, self._ordered_loader) elif ext == '.json': return jsonref.loads(response.text, base_uri=self.base_url, jsonschema=True) return response.text
def _get_content(data, base_url, ref): content = {} links = _get_list(data, 'links') properties = _get_dict(data, 'properties') if properties: for key, value in properties.items(): if not isinstance(value, dict): continue if list(value.keys()) == ['$ref']: value = _dereference(value['$ref'], ref) sub_content = _get_content(value, base_url, ref) if sub_content: content[key] = sub_content if links: for link in get_dicts(links): rel = _get_string(link, 'rel') if rel: href = _get_string(link, 'href') method = _get_string(link, 'method') schema = _get_dict(link, 'schema') schema_type = _get_list(schema, 'type') schema_properties = _get_dict(schema, 'properties') schema_required = _get_list(schema, 'required') fields = [] url = urlparse.urljoin(base_url, href) templated = uritemplate.variables(url) for item in templated: orig = item if item.startswith('(') and item.endswith(')'): item = urllib.unquote(item.strip('(').rstrip(')')) if item.startswith('#/'): components = [ component for component in item.strip('#/').split('/') if component != 'definitions' ] item = '_'.join(components).replace('-', '_') url = url.replace(orig, item) fields.append(Field(name=item, location='path', required=True)) if schema_type == ['object'] and schema_properties: fields += [ Field(name=key, required=key in schema_required) for key in schema_properties.keys() ] if rel == 'self': rel = 'read' content[rel] = Link(url=url, action=method, fields=fields) return content
def _parse_document(data, base_url=None): links = _get_dict(data, '_links') embedded = _get_dict(data, '_embedded') self = _get_dict(links, 'self') url = _get_string(self, 'href') url = urlparse.urljoin(base_url, url) title = _get_string(self, 'title') content = {} for key, value in links.items(): if key in ('self', 'curies'): continue key = _map_to_coreapi_key(key) if isinstance(value, list): if value and 'name' in value[0]: # Lists of named links should be represented inside a map. content[key] = { item['name']: _parse_link(item, base_url) for item in value if 'name' in item } else: # Lists of named links should be represented inside a list. content[key] = [ _parse_link(item, base_url) for item in value ] elif isinstance(value, dict): # Single link instance. content[key] = _parse_link(value, base_url) # Embedded resources. for key, value in embedded.items(): key = _map_to_coreapi_key(key) if isinstance(value, list): content[key] = [_parse_document(item, base_url=url) for item in value] elif isinstance(value, dict): content[key] = _parse_document(value, base_url=url) # Data. for key, value in data.items(): if key not in ('_embedded', '_links'): content[key] = value return Document(url=url, title=title, content=content)
def _primative_to_document(data, base_url): url = base_url # Determine if the document contains a self URL. links = _get_list(data, 'links') for link in get_dicts(links): href = _get_string(link, 'href') rel = _get_string(link, 'rel') if rel == 'self' and href: url = urlparse.urljoin(url, href) # Load the document content. title = _get_string(data, 'title') content = _get_content(data, url, ref=data) return Document(title=title, url=url, content=content)
def _parse_document(data, base_url=None): links = _get_dict(data, '_links') embedded = _get_dict(data, '_embedded') self = _get_dict(links, 'self') url = _get_string(self, 'href') url = urlparse.urljoin(base_url, url) title = _get_string(self, 'title') content = {} for key, value in links.items(): if key in ('self', 'curies'): continue key = _map_to_coreapi_key(key) if isinstance(value, list): if value and 'name' in value[0]: # Lists of named links should be represented inside a map. content[key] = { item['name']: _parse_link(item, base_url) for item in value if 'name' in item } else: # Lists of named links should be represented inside a list. content[key] = [_parse_link(item, base_url) for item in value] elif isinstance(value, dict): # Single link instance. content[key] = _parse_link(value, base_url) # Embedded resources. for key, value in embedded.items(): key = _map_to_coreapi_key(key) if isinstance(value, list): content[key] = [ _parse_document(item, base_url=url) for item in value ] elif isinstance(value, dict): content[key] = _parse_document(value, base_url=url) # Data. for key, value in data.items(): if key not in ('_embedded', '_links'): content[key] = value return Document(url=url, title=title, content=content)
def _render_html(node, url=None, key=None): if isinstance(node, (Document, Link)): url = urlparse.urljoin(url, node.url) if isinstance(node, Document): template = env.get_template('document.html') elif isinstance(node, Object): template = env.get_template('object.html') elif isinstance(node, Array): template = env.get_template('array.html') elif isinstance(node, Link): template = env.get_template('link.html') elif isinstance(node, Error): template = env.get_template('error.html') elif node in (True, False, None): value = {True: 'true', False: 'false', None: 'null'}[node] return "<code>%s</code>" % value elif isinstance(node, (float, int)): return "<code>%s</code>" % node else: return "<span>%s</span>" % node return template.render(node=node, render=_render_html, url=url, key=key)
def _document_to_primative(node, base_url=None): if isinstance(node, Document): url = urlparse.urljoin(base_url, node.url) links = OrderedDict() embedded = OrderedDict() data = OrderedDict() self_link = OrderedDict() self_link['href'] = url if node.title: self_link['title'] = node.title links['self'] = self_link for key, value in node.items(): if isinstance(value, Link): links[key] = _document_to_primative(value, base_url=url) elif _is_array_containing_instance(value, Link): links[key] = [ _document_to_primative(item, base_url=url) for item in value if isinstance(item, Link) ] elif _is_map_containing_instance(value, Link): links[key] = { key: _document_to_primative(val, base_url=url) for key, val in value.items() if isinstance(val, Link) } elif isinstance(value, Document): embedded[key] = _document_to_primative(value, base_url=url) elif _is_array_containing_instance(value, Document): embedded[key] = [ _document_to_primative(item, base_url=url) for item in value if isinstance(item, Document) ] elif key not in ('_links', '_embedded'): data[key] = _document_to_primative(value) ret = OrderedDict() ret['_links'] = links ret.update(data) if embedded: ret['_embedded'] = embedded return ret elif isinstance(node, Link): url = urlparse.urljoin(base_url, node.url) ret = OrderedDict() ret['href'] = url templated = [ field.name for field in node.fields if field.location == 'path' ] if templated: ret['href'] += "{?%s}" % ','.join([name for name in templated]) ret['templated'] = True return ret elif isinstance(node, Array): return [_document_to_primative(item) for item in node] elif isinstance(node, Object): return OrderedDict([(key, _document_to_primative(value)) for key, value in node.items() if not isinstance(value, (Document, Link))]) elif isinstance(node, Error): return OrderedDict([(key, _document_to_primative(value)) for key, value in node.items()]) return node
def _primative_to_document(data, base_url=None): """ Take Python primatives as returned from parsing JSON content, and return a Core API document. """ if isinstance(data, dict) and data.get('_type') == 'document': meta = data.get('_meta', {}) if not isinstance(meta, dict): meta = {} url = meta.get('url', '') if not isinstance(url, string_types): url = '' url = urlparse.urljoin(base_url, url) title = meta.get('title', '') if not isinstance(title, string_types): title = '' return Document(url=url, title=title, content={ _unescape_key(key): _primative_to_document(value, url) for key, value in data.items() if key not in ('_type', '_meta') }) elif isinstance(data, dict) and data.get('_type') == 'link': url = data.get('url', '') if not isinstance(url, string_types): url = '' url = urlparse.urljoin(base_url, url) trans = data.get('trans') if not isinstance(trans, string_types) or (trans not in _transition_types): trans = None fields = data.get('fields', []) if not isinstance(fields, list): fields = [] else: # Ignore any field items that don't match the required structure. fields = [ item for item in fields if isinstance(item, string_types) or ( isinstance(item, dict) and isinstance(item.get('name'), string_types) ) ] # Transform the strings or dicts into strings or Field instances. fields = [ item if isinstance(item, string_types) else Field(item['name'], required=bool(item.get('required', False))) for item in fields ] return Link(url=url, trans=trans, fields=fields) elif isinstance(data, dict) and data.get('_type') == 'error': messages = data.get('messages', []) if not isinstance(messages, list): messages = [] # Ignore any messages which are have incorrect type. messages = [ message for message in messages if isinstance(message, string_types) ] return Error(messages) elif isinstance(data, dict): return Object({ _unescape_key(key): _primative_to_document(value, base_url) for key, value in data.items() if key not in ('_type', '_meta') }) elif isinstance(data, list): return Array([ _primative_to_document(item, base_url) for item in data ]) return data
def _document_to_primative(node, base_url=None): if isinstance(node, Document): url = urlparse.urljoin(base_url, node.url) links = OrderedDict() embedded = OrderedDict() data = OrderedDict() self_link = OrderedDict() self_link['href'] = url if node.title: self_link['title'] = node.title links['self'] = self_link for key, value in node.items(): if isinstance(value, Link): links[key] = _document_to_primative(value, base_url=url) elif _is_array_containing_instance(value, Link): links[key] = [ _document_to_primative(item, base_url=url) for item in value if isinstance(item, Link) ] elif _is_map_containing_instance(value, Link): links[key] = { key: _document_to_primative(val, base_url=url) for key, val in value.items() if isinstance(val, Link) } elif isinstance(value, Document): embedded[key] = _document_to_primative(value, base_url=url) elif _is_array_containing_instance(value, Document): embedded[key] = [ _document_to_primative(item, base_url=url) for item in value if isinstance(item, Document) ] elif key not in ('_links', '_embedded'): data[key] = _document_to_primative(value) ret = OrderedDict() ret['_links'] = links ret.update(data) if embedded: ret['_embedded'] = embedded return ret elif isinstance(node, Link): url = urlparse.urljoin(base_url, node.url) ret = OrderedDict() ret['href'] = url templated = [field.name for field in node.fields if field.location == 'path'] if templated: ret['href'] += "{?%s}" % ','.join([name for name in templated]) ret['templated'] = True return ret elif isinstance(node, Array): return [ _document_to_primative(item) for item in node ] elif isinstance(node, Object): return OrderedDict([ (key, _document_to_primative(value)) for key, value in node.items() if not isinstance(value, (Document, Link)) ]) elif isinstance(node, Error): return OrderedDict([ (key, _document_to_primative(value)) for key, value in node.items() ]) return node
def _primitive_to_document(data, base_url=None): """ Take Python primitives as returned from parsing JSON content, and return a Core API document. """ if isinstance(data, dict) and data.get("_type") == "document": # Document meta = _get_dict(data, "_meta") url = _get_string(meta, "url") url = urlparse.urljoin(base_url, url) title = _get_string(meta, "title") description = _get_string(meta, "description") content = _get_content(data, base_url=url) return Document( url=url, title=title, description=description, media_type="application/coreapi+json", content=content, ) if isinstance(data, dict) and data.get("_type") == "error": # Error meta = _get_dict(data, "_meta") title = _get_string(meta, "title") content = _get_content(data, base_url=base_url) return Error(title=title, content=content) elif isinstance(data, dict) and data.get("_type") == "link": # Link url = _get_string(data, "url") url = urlparse.urljoin(base_url, url) action = _get_string(data, "action") encoding = _get_string(data, "encoding") transform = _get_string(data, "transform") title = _get_string(data, "title") description = _get_string(data, "description") fields = _get_list(data, "fields") fields = [ Field( name=_get_string(item, "name"), required=_get_bool(item, "required"), location=_get_string(item, "location"), schema=_get_schema(item, "schema"), ) for item in fields if isinstance(item, dict) ] return Link( url=url, action=action, encoding=encoding, transform=transform, title=title, description=description, fields=fields, ) elif isinstance(data, dict): # Map content = _get_content(data, base_url=base_url) return Object(content) elif isinstance(data, list): # Array content = [_primitive_to_document(item, base_url) for item in data] return Array(content) # String, Integer, Number, Boolean, null. return data
def _parse_document(data, base_url=None): schema_url = base_url base_url = _get_document_base_url(data, base_url) info = _get_dict(data, 'info') title = _get_string(info, 'title') paths = _get_dict(data, 'paths') content = {} for path in paths.keys(): url = urlparse.urljoin(base_url, path.lstrip('/')) spec = _get_dict(paths, path) default_parameters = get_dicts(_get_list(spec, 'parameters')) for action in spec.keys(): action = action.lower() if action not in ('get', 'put', 'post', 'delete', 'options', 'head', 'patch'): continue operation = _get_dict(spec, action) # Determine any fields on the link. fields = [] parameters = get_dicts(_get_list(operation, 'parameters', default_parameters), dereference_using=data) for parameter in parameters: name = _get_string(parameter, 'name') location = _get_string(parameter, 'in') required = _get_bool(parameter, 'required', default=(location == 'path')) description = _get_string(parameter, 'description') if location == 'body': schema = _get_dict(parameter, 'schema', dereference_using=data) expanded = _expand_schema(schema) if expanded is not None: expanded_fields = [ Field(name=field_name, location='form', required=is_required, description=description) for field_name, is_required in expanded if not any([field.name == name for field in fields]) ] fields += expanded_fields else: field = Field(name=name, location='body', required=True, description=description) fields.append(field) else: field = Field(name=name, location=location, required=required, description=description) fields.append(field) link = Link(url=url, action=action, fields=fields) # Add the link to the document content. tags = get_strings(_get_list(operation, 'tags')) operation_id = _get_string(operation, 'operationId') if tags: for tag in tags: if tag not in content: content[tag] = {} content[tag][operation_id] = link else: content[operation_id] = link return Document(url=schema_url, title=title, content=content)