Factor out json schema object processing since swagger uses it too. Hook swagger up.
This commit is contained in:
parent
d090389d01
commit
fe7ffafc15
2 changed files with 120 additions and 92 deletions
|
@ -54,6 +54,7 @@ paths:
|
||||||
description: "The content downloaded."
|
description: "The content downloaded."
|
||||||
schema:
|
schema:
|
||||||
type: file
|
type: file
|
||||||
|
name: content
|
||||||
"/thumbnail/{serverName}/{mediaId}":
|
"/thumbnail/{serverName}/{mediaId}":
|
||||||
get:
|
get:
|
||||||
summary: "Download a thumbnail of the content from the content repository."
|
summary: "Download a thumbnail of the content from the content repository."
|
||||||
|
@ -89,5 +90,6 @@ paths:
|
||||||
description: "A thumbnail of the requested content."
|
description: "A thumbnail of the requested content."
|
||||||
schema:
|
schema:
|
||||||
type: file
|
type: file
|
||||||
|
name: content
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,95 @@ import os
|
||||||
import subprocess
|
import subprocess
|
||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
|
def get_json_schema_object_fields(obj, enforce_title=False):
|
||||||
|
# Algorithm:
|
||||||
|
# f.e. property => add field info (if field is object then recurse)
|
||||||
|
if obj.get("type") != "object":
|
||||||
|
raise Exception(
|
||||||
|
"get_json_schema_object_fields: Object %s isn't an object." % obj
|
||||||
|
)
|
||||||
|
if enforce_title and not obj.get("title"):
|
||||||
|
raise Exception(
|
||||||
|
"get_json_schema_object_fields: Nested object %s doesn't have a title." % obj
|
||||||
|
)
|
||||||
|
|
||||||
|
required_keys = obj.get("required")
|
||||||
|
if not required_keys:
|
||||||
|
required_keys = []
|
||||||
|
|
||||||
|
fields = {
|
||||||
|
"title": obj.get("title"),
|
||||||
|
"rows": []
|
||||||
|
}
|
||||||
|
tables = [fields]
|
||||||
|
|
||||||
|
props = obj.get("properties")
|
||||||
|
parents = obj.get("allOf")
|
||||||
|
if not props and not parents:
|
||||||
|
raise Exception(
|
||||||
|
"Object %s has no properties or parents." % obj
|
||||||
|
)
|
||||||
|
if not props: # parents only
|
||||||
|
return [{
|
||||||
|
"title": obj["title"],
|
||||||
|
"parent": parents[0]["$ref"],
|
||||||
|
"no-table": True
|
||||||
|
}]
|
||||||
|
|
||||||
|
for key_name in sorted(props):
|
||||||
|
value_type = None
|
||||||
|
required = key_name in required_keys
|
||||||
|
desc = props[key_name].get("description", "")
|
||||||
|
|
||||||
|
if props[key_name]["type"] == "object":
|
||||||
|
if props[key_name].get("additionalProperties"):
|
||||||
|
# not "really" an object, just a KV store
|
||||||
|
value_type = (
|
||||||
|
"{string: %s}" %
|
||||||
|
props[key_name]["additionalProperties"]["type"]
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
nested_object = get_json_schema_object_fields(
|
||||||
|
props[key_name],
|
||||||
|
enforce_title=True
|
||||||
|
)
|
||||||
|
value_type = "{%s}" % nested_object[0]["title"]
|
||||||
|
|
||||||
|
if not nested_object[0].get("no-table"):
|
||||||
|
tables += nested_object
|
||||||
|
elif props[key_name]["type"] == "array":
|
||||||
|
# if the items of the array are objects then recurse
|
||||||
|
if props[key_name]["items"]["type"] == "object":
|
||||||
|
nested_object = get_json_schema_object_fields(
|
||||||
|
props[key_name]["items"],
|
||||||
|
enforce_title=True
|
||||||
|
)
|
||||||
|
value_type = "[%s]" % nested_object[0]["title"]
|
||||||
|
tables += nested_object
|
||||||
|
else:
|
||||||
|
value_type = "[%s]" % props[key_name]["items"]["type"]
|
||||||
|
else:
|
||||||
|
value_type = props[key_name]["type"]
|
||||||
|
if props[key_name].get("enum"):
|
||||||
|
if len(props[key_name].get("enum")) > 1:
|
||||||
|
value_type = "enum"
|
||||||
|
desc += (
|
||||||
|
" One of: %s" % json.dumps(props[key_name]["enum"])
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
desc += (
|
||||||
|
" Must be '%s'." % props[key_name]["enum"][0]
|
||||||
|
)
|
||||||
|
|
||||||
|
fields["rows"].append({
|
||||||
|
"key": key_name,
|
||||||
|
"type": value_type,
|
||||||
|
"required": required,
|
||||||
|
"desc": desc,
|
||||||
|
"req_str": "**Required.** " if required else ""
|
||||||
|
})
|
||||||
|
return tables
|
||||||
|
|
||||||
|
|
||||||
class MatrixUnits(Units):
|
class MatrixUnits(Units):
|
||||||
|
|
||||||
|
@ -21,7 +110,10 @@ class MatrixUnits(Units):
|
||||||
"path": path,
|
"path": path,
|
||||||
"requires_auth": "security" in single_api,
|
"requires_auth": "security" in single_api,
|
||||||
"rate_limited": 429 in single_api.get("responses", {}),
|
"rate_limited": 429 in single_api.get("responses", {}),
|
||||||
"req_params": []
|
"req_params": [],
|
||||||
|
"responses": [
|
||||||
|
# { code: 200, [ {row_info} ]}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
self.log(".o.O.o. Endpoint: %s %s" % (method, path))
|
self.log(".o.O.o. Endpoint: %s %s" % (method, path))
|
||||||
for param in single_api.get("parameters", []):
|
for param in single_api.get("parameters", []):
|
||||||
|
@ -72,6 +164,29 @@ class MatrixUnits(Units):
|
||||||
"desc": json_body[key]["description"]
|
"desc": json_body[key]["description"]
|
||||||
})
|
})
|
||||||
|
|
||||||
|
# add main response format first.
|
||||||
|
res200 = single_api["responses"][200]
|
||||||
|
res200params = []
|
||||||
|
if res200["schema"].get("type") != "object":
|
||||||
|
res200params = [{
|
||||||
|
"title": "Response",
|
||||||
|
"rows": [{
|
||||||
|
"key": res200["schema"]["name"],
|
||||||
|
"type": res200["schema"]["type"],
|
||||||
|
"desc": res200["schema"].get("description", "")
|
||||||
|
}]
|
||||||
|
}]
|
||||||
|
elif res200["schema"].get("properties"):
|
||||||
|
res200params = get_json_schema_object_fields(
|
||||||
|
res200["schema"]
|
||||||
|
)
|
||||||
|
ok_res = {
|
||||||
|
"code": 200,
|
||||||
|
"http": "200 OK",
|
||||||
|
"desc": res200["description"],
|
||||||
|
"params": res200params
|
||||||
|
}
|
||||||
|
endpoint["responses"].append(ok_res)
|
||||||
|
|
||||||
endpoints.append(endpoint)
|
endpoints.append(endpoint)
|
||||||
return {
|
return {
|
||||||
|
@ -135,95 +250,6 @@ class MatrixUnits(Units):
|
||||||
path = "../event-schemas/schema/v1"
|
path = "../event-schemas/schema/v1"
|
||||||
schemata = {}
|
schemata = {}
|
||||||
|
|
||||||
def get_content_fields(obj, enforce_title=False):
|
|
||||||
# Algorithm:
|
|
||||||
# f.e. property => add field info (if field is object then recurse)
|
|
||||||
if obj.get("type") != "object":
|
|
||||||
raise Exception(
|
|
||||||
"get_content_fields: Object %s isn't an object." % obj
|
|
||||||
)
|
|
||||||
if enforce_title and not obj.get("title"):
|
|
||||||
raise Exception(
|
|
||||||
"get_content_fields: Nested object %s doesn't have a title." % obj
|
|
||||||
)
|
|
||||||
|
|
||||||
required_keys = obj.get("required")
|
|
||||||
if not required_keys:
|
|
||||||
required_keys = []
|
|
||||||
|
|
||||||
fields = {
|
|
||||||
"title": obj.get("title"),
|
|
||||||
"rows": []
|
|
||||||
}
|
|
||||||
tables = [fields]
|
|
||||||
|
|
||||||
props = obj.get("properties")
|
|
||||||
parents = obj.get("allOf")
|
|
||||||
if not props and not parents:
|
|
||||||
raise Exception(
|
|
||||||
"Object %s has no properties or parents." % obj
|
|
||||||
)
|
|
||||||
if not props: # parents only
|
|
||||||
return [{
|
|
||||||
"title": obj["title"],
|
|
||||||
"parent": parents[0]["$ref"],
|
|
||||||
"no-table": True
|
|
||||||
}]
|
|
||||||
|
|
||||||
for key_name in sorted(props):
|
|
||||||
value_type = None
|
|
||||||
required = key_name in required_keys
|
|
||||||
desc = props[key_name].get("description", "")
|
|
||||||
|
|
||||||
if props[key_name]["type"] == "object":
|
|
||||||
if props[key_name].get("additionalProperties"):
|
|
||||||
# not "really" an object, just a KV store
|
|
||||||
value_type = (
|
|
||||||
"{string: %s}" %
|
|
||||||
props[key_name]["additionalProperties"]["type"]
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
nested_object = get_content_fields(
|
|
||||||
props[key_name],
|
|
||||||
enforce_title=True
|
|
||||||
)
|
|
||||||
value_type = "{%s}" % nested_object[0]["title"]
|
|
||||||
|
|
||||||
if not nested_object[0].get("no-table"):
|
|
||||||
tables += nested_object
|
|
||||||
elif props[key_name]["type"] == "array":
|
|
||||||
# if the items of the array are objects then recurse
|
|
||||||
if props[key_name]["items"]["type"] == "object":
|
|
||||||
nested_object = get_content_fields(
|
|
||||||
props[key_name]["items"],
|
|
||||||
enforce_title=True
|
|
||||||
)
|
|
||||||
value_type = "[%s]" % nested_object[0]["title"]
|
|
||||||
tables += nested_object
|
|
||||||
else:
|
|
||||||
value_type = "[%s]" % props[key_name]["items"]["type"]
|
|
||||||
else:
|
|
||||||
value_type = props[key_name]["type"]
|
|
||||||
if props[key_name].get("enum"):
|
|
||||||
if len(props[key_name].get("enum")) > 1:
|
|
||||||
value_type = "enum"
|
|
||||||
desc += (
|
|
||||||
" One of: %s" % json.dumps(props[key_name]["enum"])
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
desc += (
|
|
||||||
" Must be '%s'." % props[key_name]["enum"][0]
|
|
||||||
)
|
|
||||||
|
|
||||||
fields["rows"].append({
|
|
||||||
"key": key_name,
|
|
||||||
"type": value_type,
|
|
||||||
"required": required,
|
|
||||||
"desc": desc,
|
|
||||||
"req_str": "**Required.** " if required else ""
|
|
||||||
})
|
|
||||||
return tables
|
|
||||||
|
|
||||||
for filename in os.listdir(path):
|
for filename in os.listdir(path):
|
||||||
if not filename.startswith("m."):
|
if not filename.startswith("m."):
|
||||||
continue
|
continue
|
||||||
|
@ -270,7 +296,7 @@ class MatrixUnits(Units):
|
||||||
schema["desc"] = json_schema.get("description", "")
|
schema["desc"] = json_schema.get("description", "")
|
||||||
|
|
||||||
# walk the object for field info
|
# walk the object for field info
|
||||||
schema["content_fields"] = get_content_fields(
|
schema["content_fields"] = get_json_schema_object_fields(
|
||||||
Units.prop(json_schema, "properties/content")
|
Units.prop(json_schema, "properties/content")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue