-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathgenerate_openapi_schema.py
More file actions
123 lines (113 loc) · 3.5 KB
/
Copy pathgenerate_openapi_schema.py
File metadata and controls
123 lines (113 loc) · 3.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import contextlib
import io
import json
from argparse import ArgumentParser
from pathlib import Path
import yaml
from fastapi.openapi.utils import get_openapi
import murfey
from murfey.cli import LineWrapHelpFormatter, PrettierDumper
def run():
# Set up argument parser
parser = ArgumentParser(
description=(
"Generates an OpenAPI schema of the chosen FastAPI server "
"and outputs it as either a JSON or YAML file"
),
formatter_class=LineWrapHelpFormatter,
)
parser.add_argument(
"--target",
"-t",
default="server",
help=(
"The target FastAPI server to construct the OpenAPI schema for. \n"
"OPTIONS: instrument-server | server \n"
"DEFAULT: server"
),
)
parser.add_argument(
"--output",
"-o",
default="yaml",
help=(
"Set the output format of the OpenAPI schema. \n"
"OPTIONS: json | yaml \n"
"DEFAULT: yaml"
),
)
parser.add_argument(
"--to-file",
"-f",
default="",
help=(
"Alternative file path and file name to save the schema as. "
"Can be a relative or absolute path. \n"
"By default, the schema will be saved to 'murfey/utils/', "
"and it will have the name 'openapi.json' or 'openapi.yaml'."
),
)
parser.add_argument(
"--debug",
action="store_true",
default=False,
help="Shows additional steps when setting ",
)
args = parser.parse_args()
# Load the relevant FastAPI app
target = str(args.target).lower()
# Silence output during import; only return genuine errors
buffer = io.StringIO()
with contextlib.redirect_stdout(buffer), contextlib.redirect_stderr(buffer):
if target == "server":
from murfey.server.main import app
elif target == "instrument-server":
from murfey.instrument_server.main import app
else:
raise ValueError(
"Unexpected value for target server. It must be one of "
"'instrument-server' or 'server'"
)
if args.debug:
print(f"Imported FastAPI app for {target}")
if not app.openapi_schema:
schema = get_openapi(
title=app.title,
version=app.version,
openapi_version=app.openapi_version,
description=app.description,
routes=app.routes,
)
if args.debug:
print(f"Constructed OpenAPI schema for {target}")
else:
schema = app.openapi_schema
if args.debug:
print(f"Loaded OpenAPI schema for {target}")
output = str(args.output).lower()
if output not in ("json", "yaml"):
raise ValueError(
"Invalid file format selected. Output must be either 'json' or 'yaml'"
)
murfey_dir = Path(murfey.__path__[0])
save_path = (
murfey_dir / "util" / f"openapi-{target}.{output}"
if not args.to_file
else Path(args.to_file)
)
with open(save_path, "w") as f:
if output == "json":
json.dump(schema, f, indent=2)
else:
yaml.dump(
schema,
f,
Dumper=PrettierDumper,
default_flow_style=False,
sort_keys=False,
indent=2,
)
print(f"OpenAPI schema saved to {save_path}")
exit()
if __name__ == "__main__":
run()