"""Export the composed HTTP API schema without touching the operator's data root.""" from __future__ import annotations import json import os import tempfile from pathlib import Path from typing import Any from gewu.bootstrap.app import create_local_app ROOT = Path(__file__).resolve().parents[1] DESTINATION = ROOT / "schema" / "v1" / "openapi.json" def componentize_record_schema( name: str, record_schema: dict[str, Any], components: dict[str, Any] ) -> None: definitions = record_schema.pop("$defs", {}) def rewrite_local_refs(value: Any) -> Any: if isinstance(value, list): return [rewrite_local_refs(item) for item in value] if not isinstance(value, dict): return value rewritten = {key: rewrite_local_refs(item) for key, item in value.items() if key != "$defs"} reference = rewritten.get("$ref") if isinstance(reference, str) and reference.startswith("#/$defs/"): definition_name = reference.removeprefix("#/$defs/") rewritten["$ref"] = f"#/components/schemas/{name}__{definition_name}" return rewritten for definition_name, definition in definitions.items(): component_name = f"{name}__{definition_name}" components.setdefault(component_name, rewrite_local_refs(definition)) components.setdefault(name, rewrite_local_refs(record_schema)) def main() -> None: previous_data_root = os.environ.get("GEWU_DATA_ROOT") with tempfile.TemporaryDirectory(prefix="gewu-openapi-") as temporary: os.environ["GEWU_DATA_ROOT"] = str(Path(temporary) / "data") try: schema: dict[str, Any] = create_local_app().openapi() finally: if previous_data_root is None: os.environ.pop("GEWU_DATA_ROOT", None) else: os.environ["GEWU_DATA_ROOT"] = previous_data_root schema_components = schema.setdefault("components", {}).setdefault("schemas", {}) for record_schema in sorted((ROOT / "schema" / "v1" / "records").glob("*.schema.json")): component_name = record_schema.name.removesuffix(".schema.json") schema_value = json.loads(record_schema.read_text(encoding="utf-8")) componentize_record_schema(component_name, schema_value, schema_components) DESTINATION.parent.mkdir(parents=True, exist_ok=True) DESTINATION.write_text( json.dumps(schema, ensure_ascii=False, indent=2, sort_keys=True) + "\n", encoding="utf-8", ) if __name__ == "__main__": main()