72 lines
2.4 KiB
Python
72 lines
2.4 KiB
Python
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}个操作)"
|
||
)
|
||
)
|