"""matchmaking-v2 — FastAPI app (course-service mold). Serves: the agent card (discovery), /a2a/tasks (orchestrator entry), /api/v1/health. On-demand by design — no corpus DB, no nightly ingestion. """ from __future__ import annotations import logging from contextlib import asynccontextmanager from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from app.adk.worker import RedisStreamWorker from app.api.v1 import router as api_router from app.a2a.card import router as a2a_card_router from app.a2a.tasks import router as a2a_tasks_router from app.config import get_settings logging.basicConfig(level=get_settings().LOG_LEVEL) _settings = get_settings() _worker = RedisStreamWorker(redis_url=_settings.ORCHESTRATOR_REDIS_URL or _settings.REDIS_URL) @asynccontextmanager async def lifespan(_: FastAPI): from app.db.repo import init_db await init_db() # create the feed table if DATABASE_URL is set (best-effort) await _worker.start() try: yield finally: await _worker.stop() def create_app() -> FastAPI: s = get_settings() app = FastAPI(title="Matchmaking v2", version="2.0.0", lifespan=lifespan) app.add_middleware( CORSMiddleware, allow_origins=s.cors_origins_list, allow_credentials=s.cors_origins_list != ["*"], allow_methods=["*"], allow_headers=["*"], ) app.include_router(api_router, prefix=s.API_PREFIX) app.include_router(a2a_card_router) app.include_router(a2a_tasks_router) return app app = create_app()