107 lines
3.8 KiB
Python
107 lines
3.8 KiB
Python
import threading
|
|
|
|
from fastapi import FastAPI
|
|
from fastapi.middleware.cors import CORSMiddleware
|
|
|
|
from app.api.routes import auth, dashboard, settings as settings_routes, imports, detect, domains, exports, logs, runtime, juming, ops, ops_agent, ops_release, sensitive_words
|
|
from app.core.config import settings as app_settings
|
|
from app.services.build_info_service import get_runtime_build_info, remember_registered_route_paths
|
|
from app.services.cluster_runtime_service import ensure_runtime_schema, register_local_control_heartbeat
|
|
from app.services.ops_agent_service import ensure_ops_agent_schema
|
|
from app.services.ops_job_service import ensure_ops_schema
|
|
from app.services.ops_release_service import ensure_ops_release_schema
|
|
_heartbeat_stop_event = threading.Event()
|
|
_bootstrap_started = False
|
|
_bootstrap_lock = threading.Lock()
|
|
|
|
|
|
def _bootstrap_runtime_prerequisites() -> None:
|
|
for task in (
|
|
ensure_runtime_schema,
|
|
ensure_ops_schema,
|
|
ensure_ops_agent_schema,
|
|
ensure_ops_release_schema,
|
|
register_local_control_heartbeat,
|
|
):
|
|
try:
|
|
task()
|
|
except Exception:
|
|
# Startup must not block API listening on slow schema checks or DB stalls.
|
|
pass
|
|
|
|
|
|
def _control_heartbeat_loop() -> None:
|
|
while not _heartbeat_stop_event.is_set():
|
|
try:
|
|
register_local_control_heartbeat()
|
|
except Exception:
|
|
pass
|
|
_heartbeat_stop_event.wait(30)
|
|
|
|
|
|
app = FastAPI(
|
|
title="domainCheck API",
|
|
version="0.1.0",
|
|
description="domainCheck 轻量 Web 管理后台后端骨架",
|
|
)
|
|
|
|
app.add_middleware(
|
|
CORSMiddleware,
|
|
allow_origins=app_settings.cors_origins_list,
|
|
allow_credentials=True,
|
|
allow_methods=["*"],
|
|
allow_headers=["*"],
|
|
)
|
|
|
|
|
|
@app.on_event("startup")
|
|
def on_startup() -> None:
|
|
global _bootstrap_started
|
|
remember_registered_route_paths(route.path for route in app.routes)
|
|
_heartbeat_stop_event.clear()
|
|
with _bootstrap_lock:
|
|
if not _bootstrap_started:
|
|
threading.Thread(
|
|
target=_bootstrap_runtime_prerequisites,
|
|
name="api-bootstrap",
|
|
daemon=True,
|
|
).start()
|
|
threading.Thread(target=_control_heartbeat_loop, name="control-heartbeat", daemon=True).start()
|
|
_bootstrap_started = True
|
|
|
|
|
|
@app.on_event("shutdown")
|
|
def on_shutdown() -> None:
|
|
_heartbeat_stop_event.set()
|
|
|
|
|
|
@app.get("/health")
|
|
def health() -> dict:
|
|
return {
|
|
"status": "ok",
|
|
"service": "domain-api",
|
|
"version": "0.1.0",
|
|
"api_prefix": app_settings.api_prefix,
|
|
"worker_mode": app_settings.worker_mode,
|
|
"api_host": app_settings.api_host,
|
|
"api_port": app_settings.api_port,
|
|
"build": get_runtime_build_info(route_paths=(route.path for route in app.routes)),
|
|
}
|
|
|
|
|
|
app.include_router(auth.router, prefix=app_settings.api_prefix)
|
|
app.include_router(dashboard.router, prefix=app_settings.api_prefix)
|
|
app.include_router(settings_routes.router, prefix=app_settings.api_prefix)
|
|
app.include_router(imports.router, prefix=app_settings.api_prefix)
|
|
app.include_router(detect.router, prefix=app_settings.api_prefix)
|
|
app.include_router(domains.router, prefix=app_settings.api_prefix)
|
|
app.include_router(exports.router, prefix=app_settings.api_prefix)
|
|
app.include_router(logs.router, prefix=app_settings.api_prefix)
|
|
app.include_router(runtime.router, prefix=app_settings.api_prefix)
|
|
app.include_router(juming.router, prefix=app_settings.api_prefix)
|
|
app.include_router(ops.router, prefix=app_settings.api_prefix)
|
|
app.include_router(ops_agent.router, prefix=app_settings.api_prefix)
|
|
app.include_router(ops_release.router, prefix=app_settings.api_prefix)
|
|
app.include_router(sensitive_words.router, prefix=app_settings.api_prefix)
|
|
remember_registered_route_paths(route.path for route in app.routes)
|