feat: OpenAPI assembly from endpoint records

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-31 23:59:51 +08:00
parent 0efd906a07
commit bef7a72799
2 changed files with 92 additions and 0 deletions
+56
View File
@@ -0,0 +1,56 @@
from __future__ import annotations
import re
from typing import TYPE_CHECKING, Any
if TYPE_CHECKING:
from auto_reverse.models import EndpointRecord
_PARAM = re.compile(r"\{([^}]+)\}")
def _path_params(template: str) -> list[dict[str, Any]]:
return [
{"name": name, "in": "path", "required": True, "schema": {"type": "string"}}
for name in _PARAM.findall(template)
]
def _operation(rec: EndpointRecord) -> dict[str, Any]:
op: dict[str, Any] = {}
if rec.summary:
op["summary"] = rec.summary
if rec.description:
op["description"] = rec.description
if rec.tag:
op["tags"] = [rec.tag]
params = _path_params(rec.signature.path_template)
params += [
{"name": q, "in": "query", "required": False, "schema": {"type": "string"}}
for q in sorted(rec.query_params)
]
if params:
op["parameters"] = params
if rec.request_schema is not None:
op["requestBody"] = {
"content": {"application/json": {"schema": rec.request_schema}}
}
status = rec.signature.status_class.replace("x", "X")
response: dict[str, Any] = {"description": rec.summary or "Response"}
if rec.response_schema is not None:
response["content"] = {"application/json": {"schema": rec.response_schema}}
op["responses"] = {status[0] + "XX": response}
return op
def build_openapi(records: list[EndpointRecord], title: str) -> dict[str, Any]:
paths: dict[str, dict[str, Any]] = {}
for rec in records:
template = rec.signature.path_template
method = rec.signature.method.lower()
paths.setdefault(template, {})[method] = _operation(rec)
return {
"openapi": "3.1.0",
"info": {"title": title, "version": "0.0.0"},
"paths": paths,
}