docs-matrix-spec/scripts/dump-swagger.py
Richard van der Hoff 61ac438871
Remove the old templating system (#3445)
* Inline resolve_references in dump-swagger

Since this is the only bit of the old templating system we still use, let's
inline it.

OrederedLoader and OrderedDict are now redundant, because all dicts in Python
preserve insertion order.

* Remove the old templating system

We've now replaced the old templates with hugo, so we can get rid of this mess.
2021-10-15 11:40:03 +01:00

144 lines
4.4 KiB
Python
Executable file

#!/usr/bin/env python3
# dump-swagger reads all of the swagger API docs used in spec generation and
# outputs a JSON file which merges them all, for use as input to a swagger UI
# viewer.
# See https://github.com/swagger-api/swagger-ui for details of swagger-ui.
# Copyright 2016 OpenMarket Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import argparse
import errno
import json
import logging
import os.path
import re
import sys
import yaml
scripts_dir = os.path.dirname(os.path.abspath(__file__))
api_dir = os.path.join(os.path.dirname(scripts_dir), "data", "api")
def resolve_references(path, schema):
if isinstance(schema, dict):
# do $ref first
if '$ref' in schema:
value = schema['$ref']
path = os.path.join(os.path.dirname(path), value)
with open(path, encoding="utf-8") as f:
ref = yaml.safe_load(f)
result = resolve_references(path, ref)
del schema['$ref']
else:
result = {}
for key, value in schema.items():
result[key] = resolve_references(path, value)
return result
elif isinstance(schema, list):
return [resolve_references(path, value) for value in schema]
else:
return schema
parser = argparse.ArgumentParser(
"dump-swagger.py - assemble the Swagger specs into a single JSON file"
)
parser.add_argument(
"--client_release", "-c", metavar="LABEL",
default="unstable",
help="""The client-server release version to generate for. Default:
%(default)s""",
)
parser.add_argument(
"-o", "--output",
default=os.path.join(scripts_dir, "swagger", "api-docs.json"),
help="File to write the output to. Default: %(default)s"
)
args = parser.parse_args()
output_file = os.path.abspath(args.output)
release_label = args.client_release
major_version = release_label
match = re.match("^(r\d+)(\.\d+)*$", major_version)
if match:
major_version = match.group(1)
logging.basicConfig()
output = {
"basePath": "/",
"consumes": ["application/json"],
"produces": ["application/json"],
"host": "matrix.org",
# The servers value will be picked up by RapiDoc to provide a way
# to switch API servers. Useful when one wants to test compliance
# of their server with the API.
"servers": [{
"url": "https://{homeserver_address}/",
"variables": {
"homeserver_address": {
"default": "matrix-client.matrix.org",
"description": "The base URL for your homeserver",
}
}
}],
"schemes": ["https"],
"info": {
"title": "Matrix Client-Server API",
"version": release_label,
},
"securityDefinitions": {},
"paths": {},
"swagger": "2.0",
}
cs_api_dir = os.path.join(api_dir, 'client-server')
with open(os.path.join(cs_api_dir, 'definitions',
'security.yaml')) as f:
output['securityDefinitions'] = yaml.safe_load(f)
for filename in os.listdir(cs_api_dir):
if not filename.endswith(".yaml"):
continue
filepath = os.path.join(cs_api_dir, filename)
print("Reading swagger API: %s" % filepath)
with open(filepath, "r") as f:
api = yaml.safe_load(f.read())
api = resolve_references(filepath, api)
basePath = api['basePath']
for path, methods in api["paths"].items():
for method, spec in methods.items():
if "tags" in spec.keys():
if path not in output["paths"]:
output["paths"][path] = {}
output["paths"][path][method] = spec
print("Generating %s" % output_file)
try:
os.makedirs(os.path.dirname(output_file))
except OSError as e:
if e.errno != errno.EEXIST:
raise
with open(output_file, "w") as f:
text = json.dumps(output, sort_keys=True, indent=4)
text = text.replace("%CLIENT_RELEASE_LABEL%", release_label)
f.write(text)