Files
crypto_trading/backend/app/main.py
T
matitos ac92dd5ac4 Observability: Prometheus metrics, log panel, runbook
- GET /api/metrics renders Prometheus text (equity, P&L, per-strategy
  equity/pnl/allocation/halted, info) with no client library.
- In-memory ring log handler (app/logs.py) exposed at GET /api/logs and a
  dashboard "Server logs" panel; Runtime mirrors bot events into the logger.
- docs/runbook.md covers deploys, the kill switch, resetting paper state and
  going live. Adds tests for metrics rendering and the log ring.
2026-09-22 17:10:38 +00:00

53 lines
1.4 KiB
Python

from __future__ import annotations
import os
from collections.abc import AsyncIterator
from contextlib import asynccontextmanager
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from app.api.routes import router
from app.config import Settings, get_settings
from app.db import init_db
from app.logs import install_log_capture
from app.runtime import Runtime
def create_app(
settings: Settings | None = None,
runtime: Runtime | None = None,
) -> FastAPI:
settings = settings or get_settings()
runtime = runtime or Runtime(settings)
@asynccontextmanager
async def lifespan(app: FastAPI) -> AsyncIterator[None]:
install_log_capture()
init_db()
app.state.runtime = runtime
yield
await runtime.shutdown()
app = FastAPI(title=settings.app_name, lifespan=lifespan)
# Baked at build time (see Dockerfile); the frontend compares its own
# version against this to self-heal from a stale cache.
app.state.build_version = os.environ.get("BUILD_VERSION", "unknown")
app.add_middleware(
CORSMiddleware,
allow_origins=settings.cors_origin_list,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
app.include_router(router)
@app.get("/")
def root() -> dict[str, str]:
return {"name": settings.app_name, "docs": "/docs"}
return app
app = create_app()