zulip/tools/create-test-api-docs

139 lines
3.6 KiB
Python
Executable File

#!/usr/bin/env python3
import html
import os
import sys
from collections import defaultdict
from typing import Any, Dict, List, Set
sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
# check for the venv
from tools.lib import sanity_check
sanity_check.check_venv(__file__)
import orjson
Call = Dict[str, Any]
def clean_up_pattern(s: str) -> str:
paren_level = 0
in_braces = False
result = ""
prior_char = None
for c in s:
if c == "(":
paren_level += 1
if c == "<" and prior_char == "P":
in_braces = True
if in_braces or (paren_level == 0):
if c != "?":
result += c
if c == ")":
paren_level -= 1
if c == ">":
in_braces = False
prior_char = c
return result
def fix_test_name(s: str) -> str:
return s.replace("zerver.tests.", "")
def create_single_page(pattern: str, out_dir: str, href: str, calls: List[Call]) -> None:
fn = out_dir + "/" + href
with open(fn, "w") as f:
f.write(
"""
<style>
.test {
margin: 20px;
}
</style>
"""
)
f.write(f"<h3>{html.escape(pattern)}</h3>\n")
calls.sort(key=lambda call: call["status_code"])
for call in calls:
f.write("<hr>")
f.write("\n{}".format(fix_test_name(call["test_name"])))
f.write('<div class="test">')
f.write(call["url"])
f.write("<br>\n")
f.write(call["method"] + "<br>\n")
f.write("status code: {}<br>\n".format(call["status_code"]))
f.write("<br>")
f.write("</div>")
def create_user_docs() -> None:
fn = "var/url_coverage.txt" # TODO: make path more robust, maybe use json suffix
out_dir = "var/api_docs"
try:
os.mkdir(out_dir)
except OSError:
pass
main_page = out_dir + "/index.html"
with open(main_page, "w") as f:
f.write(
"""
<style>
li {
list-style-type: none;
}
a {
text-decoration: none;
}
</style>
"""
)
with open(fn, "rb") as coverage:
calls = [orjson.loads(line) for line in coverage]
pattern_dict: Dict[str, List[Call]] = defaultdict(list)
for call in calls:
if "pattern" in call:
pattern = clean_up_pattern(call["pattern"])
if pattern:
pattern_dict[pattern].append(call)
patterns = set(pattern_dict.keys())
tups = [
("api/v1/external", "webhooks"),
("api/v1", "api"),
("json", "legacy"),
]
groups: Dict[str, Set[str]] = {}
for prefix, name in tups:
groups[name] = {p for p in patterns if p.startswith(prefix)}
patterns -= groups[name]
groups["other"] = patterns
for name in ["api", "legacy", "webhooks", "other"]:
f.write(name + " endpoints:\n\n")
f.write("<ul>\n")
for pattern in sorted(groups[name]):
href = pattern.replace("/", "-") + ".html"
link = f'<a href="{href}">{html.escape(pattern)}</a>'
f.write("<li>" + link + "</li>\n")
create_single_page(pattern, out_dir, href, pattern_dict[pattern])
f.write("</ul>")
f.write("\n")
print(f"open {main_page}")
if __name__ == "__main__":
create_user_docs()