Add structure for adding examples to HTTP APIs.

Use 'x-example' to add examples to parameters which are not in 'body' (swagger
doesn't define that currently). Add profile API examples. Add necessary glue
and templates to make it all work.
This commit is contained in:
Kegan Dougal 2015-06-01 14:20:24 +01:00
parent c75fd6bcae
commit 862f5a3a53
4 changed files with 66 additions and 9 deletions

View file

@ -29,12 +29,17 @@ paths:
name: userId name: userId
description: The user whose display name to set. description: The user whose display name to set.
required: true required: true
x-example: "@alice:example.com"
- in: body - in: body
name: displayName name: displayName
description: The display name info. description: The display name info.
required: true required: true
schema: schema:
type: object type: object
example: |-
{
"displayname": "Alice Margatroid"
}
properties: properties:
displayname: displayname:
type: string type: string
@ -59,6 +64,7 @@ paths:
name: userId name: userId
description: The user whose display name to get. description: The user whose display name to get.
required: true required: true
x-example: "@alice:example.com"
responses: responses:
200: 200:
description: The display name for this user. description: The display name for this user.
@ -86,12 +92,17 @@ paths:
name: userId name: userId
description: The user whose avatar URL to set. description: The user whose avatar URL to set.
required: true required: true
x-example: "@alice:example.com"
- in: body - in: body
name: avatar_url name: avatar_url
description: The avatar url info. description: The avatar url info.
required: true required: true
schema: schema:
type: object type: object
example: |-
{
"avatar_url": "mxc:/matrix.org/wefh34uihSDRGhw34"
}
properties: properties:
avatar_url: avatar_url:
type: string type: string
@ -116,6 +127,7 @@ paths:
name: userId name: userId
description: The user whose avatar URL to get. description: The user whose avatar URL to get.
required: true required: true
x-example: "@alice:example.com"
responses: responses:
200: 200:
description: The avatar URL for this user. description: The avatar URL for this user.

View file

@ -27,8 +27,10 @@ if (!opts.schema) {
parser.parse(opts.schema, function(err, api, metadata) { parser.parse(opts.schema, function(err, api, metadata) {
if (!err) { if (!err) {
console.log("%s is valid.", opts.schema); console.log("%s is valid.", opts.schema);
process.exit(0);
return; return;
} }
console.log(metadata); console.log(metadata);
console.error(err); console.error(err);
process.exit(1);
}); });

View file

@ -2,10 +2,8 @@
{{(5 + (endpoint.path | length) + (endpoint.method | length)) * title_kind}} {{(5 + (endpoint.path | length) + (endpoint.method | length)) * title_kind}}
{{endpoint.desc | wrap(80)}} {{endpoint.desc | wrap(80)}}
{{":Rate-limited: Yes." if endpoint.rate_limited else "" }}
{{":Rate-limited: Yes." if endpoint.rate_limited else ""}} {{":Requires auth: Yes." if endpoint.requires_auth else "" }}
{{":Requires auth: Yes." if endpoint.requires_auth else ""}}
Request format: Request format:
================== ================= =========== =============================== ================== ================= =========== ===============================
@ -17,3 +15,10 @@ param.loc|length)}}{{param.desc|indent(12-param.type|length)|wrap(31)|indent_blo
{% endfor %} {% endfor %}
================== ================= =========== =============================== ================== ================= =========== ===============================
Example request::
{{endpoint.example.req | indent_block(2)}}
Example response::
{{endpoint.example.res | indent_block(2)}}

View file

@ -4,6 +4,7 @@ import inspect
import json import json
import os import os
import subprocess import subprocess
import urllib
import yaml import yaml
def get_json_schema_object_fields(obj, enforce_title=False): def get_json_schema_object_fields(obj, enforce_title=False):
@ -113,7 +114,11 @@ class MatrixUnits(Units):
"req_params": [], "req_params": [],
"responses": [ "responses": [
# { code: 200, [ {row_info} ]} # { code: 200, [ {row_info} ]}
] ],
"example": {
"req": "",
"res": ""
}
} }
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", []):
@ -184,11 +189,44 @@ class MatrixUnits(Units):
"code": 200, "code": 200,
"http": "200 OK", "http": "200 OK",
"desc": res200["description"], "desc": res200["description"],
"params": res200params, "params": res200params
"example": res200.get("examples", {}).get(
"application/json", ""
)
} }
# add example response if it has one
endpoint["example"]["res"] = res200.get("examples", {}).get(
"application/json", ""
)
# form example request if it has one. It "has one" if all params
# have either "x-example" or a "schema" with an "example".
params_missing_examples = [
p for p in single_api.get("parameters", []) if (
"x-example" not in p and
not Units.prop(p, "schema/example")
)
]
if len(params_missing_examples) == 0:
path_template = api.get("basePath", "") + path
qps = {}
body = ""
for param in single_api.get("parameters", []):
if param["in"] == "path":
path_template = path_template.replace(
"{%s}" % param["name"], urllib.quote(
param["x-example"]
)
)
elif param["in"] == "body":
body = param["schema"]["example"]
elif param["in"] == "query":
qps[param["name"]] = qps[param["x-example"]]
query_string = "" if len(qps) == 0 else "?"+urllib.urlencode(qps)
endpoint["example"]["req"] = "%s %s%s\n%s" % (
method.upper(), path_template, query_string, body
)
else:
self.log(
"The following parameters are missing examples :( \n %s" %
[ p["name"] for p in params_missing_examples ]
)
endpoint["responses"].append(ok_res) endpoint["responses"].append(ok_res)
endpoints.append(endpoint) endpoints.append(endpoint)