feat(v2): complete v2 reimplementation

This commit is contained in:
2026-07-31 13:33:39 +02:00
parent 396219e776
commit bd107d6a30
137 changed files with 20737 additions and 155 deletions
+63
View File
@@ -0,0 +1,63 @@
#!/usr/bin/env python3
"""Export the API schema without depending on operator configuration or network I/O."""
from __future__ import annotations
import argparse
import asyncio
import json
import os
import tempfile
from pathlib import Path
from backup_tool.api.app import create_app
from backup_tool.config import Settings
def export_schema() -> dict[str, object]:
"""Build the FastAPI schema with disposable, valid settings."""
with tempfile.TemporaryDirectory(prefix="backup-tool-openapi-") as temporary:
root = Path(temporary)
key = root / "master.key"
key.write_bytes(b"openapi-export-key-material-must-be-at-least-32-bytes")
key.chmod(0o600)
for name in ("data", "repositories", "sources", "restores"):
(root / name).mkdir()
settings = Settings(
data_dir=root / "data",
database_url=f"sqlite+aiosqlite:///{root / 'data' / 'metadata.db'}",
repository_roots=(root / "repositories",),
local_source_roots=(root / "sources",),
restore_roots=(root / "restores",),
master_key_file=key,
)
app = create_app(settings)
schema = app.openapi()
# Engine construction is lazy, but dispose defensively if that changes.
asyncio.run(app.state.engine.dispose())
return schema
def main() -> int:
parser = argparse.ArgumentParser(description="Export the deterministic v2 OpenAPI document.")
parser.add_argument("--output", type=Path, default=Path("openapi/v2.json"))
parser.add_argument("--check", type=Path, metavar="PATH", help="fail when PATH differs")
arguments = parser.parse_args()
output = arguments.check or arguments.output
rendered = json.dumps(export_schema(), indent=2, sort_keys=True, ensure_ascii=False) + "\n"
if arguments.check:
if not output.is_file() or output.read_text(encoding="utf-8") != rendered:
print(f"OpenAPI drift: regenerate {output}")
return 1
print(f"OpenAPI is current: {output}")
return 0
output.parent.mkdir(parents=True, exist_ok=True)
output.write_text(rendered, encoding="utf-8")
# The schema is public source, not executable configuration.
os.chmod(output, 0o644)
print(f"Exported OpenAPI: {output}")
return 0
if __name__ == "__main__":
raise SystemExit(main())