Add project-bound OAuth MCP queries and controlled analysis with scoped evidence, limits, timeouts and a nearby-model spatial query using EPSG:4326 inputs. Default nearby searches to 200 meters and five results. Integrate investigation messaging/presentation, health/readiness and typed history; remove duplicate web search and fix online simulation and compressed baseline writes. Include project migrations 023-025; keep local credentials and demo seeding excluded. Validation: 319 focused pytest checks; real PostGIS temporary-table regression; read-only Jinqian bridge radius comparison; cross-language MCP discovery/calls.
59 lines
2.0 KiB
Python
59 lines
2.0 KiB
Python
"""Public process probes, separate from authenticated project diagnostics."""
|
|
|
|
import asyncio
|
|
|
|
from fastapi import APIRouter, Request
|
|
from fastapi.responses import JSONResponse
|
|
from sqlalchemy import text
|
|
|
|
from app.infra.db.metadb.database import engine
|
|
|
|
|
|
router = APIRouter(include_in_schema=False)
|
|
METADATA_TIMEOUT_SECONDS = 2
|
|
|
|
|
|
async def metadata_database_ready() -> bool:
|
|
try:
|
|
async with asyncio.timeout(METADATA_TIMEOUT_SECONDS):
|
|
async with engine.connect() as connection:
|
|
result = await connection.execute(text("SELECT 1"))
|
|
return result.scalar_one() == 1
|
|
except Exception:
|
|
# Public probes must not expose connection strings or driver errors.
|
|
return False
|
|
|
|
|
|
@router.get("/health")
|
|
async def health() -> dict[str, str]:
|
|
"""Check HTTP liveness without project or database dependencies."""
|
|
return {"status": "ok"}
|
|
|
|
|
|
@router.get("/ready")
|
|
async def readiness(request: Request) -> JSONResponse:
|
|
"""Check startup, metadata connectivity and the enabled MCP lifecycle."""
|
|
started = getattr(request.app.state, "startup_complete", False)
|
|
runtime = getattr(request.app.state, "mcp_runtime", None)
|
|
mcp_ready = runtime is None or runtime.ready
|
|
metadata_ready = await metadata_database_ready() if started else False
|
|
ready = started and metadata_ready and mcp_ready
|
|
return JSONResponse(
|
|
status_code=200 if ready else 503,
|
|
content={
|
|
"status": "ready" if ready else "not_ready",
|
|
"checks": {
|
|
"startup": "ready" if started else "not_ready",
|
|
"metadata_database": (
|
|
"not_checked" if not started
|
|
else "ready" if metadata_ready else "unavailable"
|
|
),
|
|
"mcp_transport": (
|
|
"disabled" if runtime is None
|
|
else "ready" if mcp_ready else "not_ready"
|
|
),
|
|
},
|
|
},
|
|
headers={"Cache-Control": "no-store"},
|
|
)
|