factory/apps/utils/management/commands/build_swagger.py

72 lines
2.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import json
import os
from io import StringIO
from pathlib import Path
from django.conf import settings
from django.core.management import BaseCommand, CommandError, call_command
class Command(BaseCommand):
help = "生成供 Swagger UI 和 ReDoc 使用的静态 Swagger JSON"
def add_arguments(self, parser):
parser.add_argument(
"--output",
help="输出路径,默认使用 settings.SWAGGER_SCHEMA_PATH",
)
parser.add_argument(
"--url",
help="文档中的 API 根地址,默认使用 settings.BASE_URL",
)
def handle(self, *args, **options):
target = Path(options["output"] or settings.SWAGGER_SCHEMA_PATH)
if not target.is_absolute():
target = Path(settings.BASE_DIR) / target
target = target.resolve()
target.parent.mkdir(parents=True, exist_ok=True)
temporary = target.with_name(f".{target.name}.{os.getpid()}.tmp")
try:
output = StringIO()
call_command(
"generate_swagger",
"-",
format="json",
api_url=options["url"] or settings.BASE_URL,
mock=True,
verbosity=0,
stdout=output,
)
content = output.getvalue()
schema = json.loads(content)
if schema.get("swagger") != "2.0" or not schema.get("paths"):
raise CommandError("生成的 Swagger 文档缺少版本或接口路径")
content = json.dumps(
schema,
ensure_ascii=False,
separators=(",", ":"),
)
temporary.write_text(content, encoding="utf-8")
os.replace(temporary, target)
except Exception as exc:
if isinstance(exc, CommandError):
raise
raise CommandError(f"生成 Swagger 文档失败:{exc}") from exc
finally:
temporary.unlink(missing_ok=True)
operation_count = sum(
method.lower() in {"get", "post", "put", "patch", "delete"}
for path in schema["paths"].values()
for method in path
)
self.stdout.write(
self.style.SUCCESS(
f"Swagger文档已生成{target} "
f"{len(schema['paths'])}个路径,{operation_count}个操作)"
)
)