102 lines
3.4 KiB
Python
102 lines
3.4 KiB
Python
import logging
|
||
import os
|
||
from collections.abc import AsyncIterator
|
||
from contextlib import asynccontextmanager
|
||
|
||
import sentry_sdk
|
||
from fastapi import FastAPI
|
||
from fastapi.middleware.cors import CORSMiddleware
|
||
from sentry_sdk.integrations.celery import CeleryIntegration
|
||
from sentry_sdk.integrations.fastapi import FastApiIntegration
|
||
from sentry_sdk.integrations.httpx import HttpxIntegration
|
||
from sentry_sdk.integrations.logging import LoggingIntegration
|
||
from sentry_sdk.integrations.sqlalchemy import SqlalchemyIntegration
|
||
from sentry_sdk.integrations.starlette import StarletteIntegration
|
||
|
||
from app.api.v1 import (
|
||
admin_cadastre,
|
||
admin_etl,
|
||
admin_jobs,
|
||
admin_leads,
|
||
admin_scrape,
|
||
admin_weight_profiles,
|
||
analytics,
|
||
concepts,
|
||
parcels,
|
||
photos,
|
||
)
|
||
from app.core.config import settings
|
||
from app.observability.sentry_scrub import scrub_sensitive_query
|
||
|
||
logger = logging.getLogger(__name__)
|
||
|
||
# Инициализируем SDK до создания FastAPI app, чтобы все инструменты
|
||
# (middleware, маршруты) видели активный client с самого старта процесса.
|
||
# GlitchTip не поддерживает profiling — profiles_sample_rate=0.0.
|
||
if settings.glitchtip_dsn:
|
||
sentry_sdk.init(
|
||
dsn=settings.glitchtip_dsn,
|
||
environment=settings.environment,
|
||
release=os.getenv("GIT_SHA") or os.getenv("SENTRY_RELEASE") or "unknown",
|
||
traces_sample_rate=settings.glitchtip_traces_sample_rate,
|
||
profiles_sample_rate=0.0,
|
||
send_default_pii=False,
|
||
before_send_transaction=scrub_sensitive_query,
|
||
integrations=[
|
||
StarletteIntegration(),
|
||
FastApiIntegration(),
|
||
CeleryIntegration(monitor_beat_tasks=True),
|
||
SqlalchemyIntegration(),
|
||
HttpxIntegration(),
|
||
LoggingIntegration(level=logging.INFO, event_level=logging.ERROR),
|
||
],
|
||
)
|
||
logger.info(
|
||
"GlitchTip SDK initialised (env=%s, traces=%.2f)",
|
||
settings.environment,
|
||
settings.glitchtip_traces_sample_rate,
|
||
)
|
||
|
||
|
||
@asynccontextmanager
|
||
async def lifespan(app: FastAPI) -> AsyncIterator[None]:
|
||
yield
|
||
|
||
|
||
app = FastAPI(title="GenDesign API", version="0.1.0", lifespan=lifespan)
|
||
|
||
app.add_middleware(
|
||
CORSMiddleware,
|
||
allow_origins=settings.cors_origins,
|
||
allow_credentials=True,
|
||
allow_methods=["*"],
|
||
allow_headers=["*"],
|
||
)
|
||
|
||
app.include_router(concepts.router, prefix="/api/v1/concepts", tags=["concepts"])
|
||
app.include_router(parcels.router, prefix="/api/v1/parcels", tags=["parcels"])
|
||
app.include_router(analytics.router, prefix="/api/v1/analytics", tags=["analytics"])
|
||
app.include_router(admin_scrape.router, prefix="/api/v1/admin/scrape", tags=["admin"])
|
||
app.include_router(admin_jobs.router, prefix="/api/v1/admin/jobs", tags=["admin"])
|
||
app.include_router(admin_leads.router, prefix="/api/v1/admin/leads", tags=["admin"])
|
||
app.include_router(
|
||
admin_weight_profiles.router,
|
||
prefix="/api/v1/admin/site-finder/weight-profiles",
|
||
tags=["admin", "site-finder"],
|
||
)
|
||
app.include_router(photos.router, prefix="/api/v1/photos", tags=["photos"])
|
||
app.include_router(
|
||
admin_cadastre.router,
|
||
prefix="/api/v1/admin/cadastre",
|
||
tags=["admin", "cadastre"],
|
||
)
|
||
app.include_router(
|
||
admin_etl.router,
|
||
prefix="/api/v1/admin/etl",
|
||
tags=["admin", "etl"],
|
||
)
|
||
|
||
|
||
@app.get("/health")
|
||
async def health() -> dict[str, str]:
|
||
return {"status": "ok", "environment": settings.environment}
|