import asyncio import logging from contextlib import asynccontextmanager from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from sqlalchemy import select from app.api.router import api_router from app.core.config import get_settings from app.core.db import SessionLocal from app.core.logging import configure_logging from app.core.security import hash_password from app.models.models import User from app.services.collector import collector_loop settings = get_settings() configure_logging(settings.log_level) logger = logging.getLogger(__name__) collector_task: asyncio.Task | None = None collector_stop_event = asyncio.Event() async def ensure_admin_user() -> None: async with SessionLocal() as db: admin = await db.scalar(select(User).where(User.email == settings.init_admin_email)) if admin: return user = User( email=settings.init_admin_email, password_hash=hash_password(settings.init_admin_password), role="admin", ) db.add(user) await db.commit() logger.info("created initial admin user") @asynccontextmanager async def lifespan(_: FastAPI): global collector_task await ensure_admin_user() collector_task = asyncio.create_task(collector_loop(collector_stop_event)) try: yield finally: collector_stop_event.set() if collector_task: await collector_task app = FastAPI(title=settings.app_name, lifespan=lifespan) app.add_middleware( CORSMiddleware, allow_origins=settings.cors_origins_list, allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) app.include_router(api_router, prefix=settings.api_v1_prefix)