Parce docstring of http handlers to increase OAS Remove the not expected definitions key in the OAS
134 lines
3.3 KiB
Python
134 lines
3.3 KiB
Python
import argparse
|
|
import importlib
|
|
import json
|
|
from typing import Dict, Protocol, Optional, Callable
|
|
import sys
|
|
from .view import generate_oas
|
|
|
|
|
|
class YamlModule(Protocol):
|
|
"""
|
|
Yaml Module type hint
|
|
"""
|
|
|
|
def dump(self, data) -> str:
|
|
pass
|
|
|
|
|
|
yaml: Optional[YamlModule]
|
|
|
|
try:
|
|
import yaml
|
|
except ImportError:
|
|
yaml = None
|
|
|
|
|
|
def application_type(value):
|
|
"""
|
|
Return aiohttp application defined in the value.
|
|
"""
|
|
try:
|
|
module_name, app_name = value.split(":")
|
|
except ValueError:
|
|
module_name, app_name = value, "app"
|
|
|
|
module = importlib.import_module(module_name)
|
|
try:
|
|
if app_name.endswith("()"):
|
|
app_name = app_name.strip("()")
|
|
factory_app = getattr(module, app_name)
|
|
return factory_app()
|
|
return getattr(module, app_name)
|
|
|
|
except AttributeError as error:
|
|
raise argparse.ArgumentTypeError(error) from error
|
|
|
|
|
|
def base_oas_file_type(value) -> Dict:
|
|
"""
|
|
Load base oas file
|
|
"""
|
|
try:
|
|
with open(value) as oas_file:
|
|
data = oas_file.read()
|
|
except OSError as error:
|
|
raise argparse.ArgumentTypeError(error) from error
|
|
|
|
return json.loads(data)
|
|
|
|
|
|
def format_type(value) -> Callable:
|
|
"""
|
|
Date Dumper one of (json, yaml)
|
|
"""
|
|
dumpers = {"json": lambda data: json.dumps(data, sort_keys=True, indent=4)}
|
|
if yaml is not None:
|
|
dumpers["yaml"] = yaml.dump
|
|
|
|
try:
|
|
return dumpers[value]
|
|
except KeyError:
|
|
raise argparse.ArgumentTypeError(
|
|
f"Wrong format value. (allowed values: {tuple(dumpers.keys())})"
|
|
) from None
|
|
|
|
|
|
def setup(parser: argparse.ArgumentParser):
|
|
parser.add_argument(
|
|
"apps",
|
|
metavar="APP",
|
|
type=application_type,
|
|
nargs="*",
|
|
help="The name of the module containing the asyncio.web.Application."
|
|
" By default the variable named 'app' is loaded but you can define"
|
|
" an other variable name ending the name of module with : characters"
|
|
" and the name of variable. Example: my_package.my_module:my_app"
|
|
" If your asyncio.web.Application is returned by a function, you can"
|
|
" use the syntax: my_package.my_module:my_app()",
|
|
)
|
|
parser.add_argument(
|
|
"-b",
|
|
"--base-oas-file",
|
|
metavar="FILE",
|
|
dest="base",
|
|
type=base_oas_file_type,
|
|
help="A file that will be used as base to generate OAS",
|
|
default={},
|
|
)
|
|
parser.add_argument(
|
|
"-o",
|
|
"--output",
|
|
metavar="FILE",
|
|
type=argparse.FileType("w"),
|
|
help="File to write the output",
|
|
default=sys.stdout,
|
|
)
|
|
|
|
if yaml:
|
|
help_output_format = (
|
|
"The output format, can be 'json' or 'yaml' (default is json)"
|
|
)
|
|
else:
|
|
help_output_format = "The output format, only 'json' is available install pyyaml to have yaml output format"
|
|
|
|
parser.add_argument(
|
|
"-f",
|
|
"--format",
|
|
metavar="FORMAT",
|
|
dest="formatter",
|
|
type=format_type,
|
|
help=help_output_format,
|
|
default=format_type("json"),
|
|
)
|
|
|
|
parser.set_defaults(func=show_oas)
|
|
|
|
|
|
def show_oas(args: argparse.Namespace):
|
|
"""
|
|
Display Open API Specification on the stdout.
|
|
"""
|
|
spec = args.base
|
|
spec.update(generate_oas(args.apps))
|
|
print(args.formatter(spec), file=args.output)
|