import logging from contextlib import asynccontextmanager from fastapi.middleware.cors import CORSMiddleware from fastapi import FastAPI from fastapi.responses import JSONResponse from db_setup import lifespan as db_lifespan from inbox.app import router as inbox_router from users.app import router as users_router from role.app import router as role_router from forget_password.app import router as forget_password_router from job.app import router as candidate_router from notifications.app import router as confirmation_router from analytics.app import router as analytics_router from reports.app import router as reports_router from offer.app import router as offer_router from tasks.app import router as tasks_router from assessments.app import router as assessments_router from org_settings.app import router as org_settings_router from saved_search.app import router as saved_search_router from search.app import router as search_router from interview.app import router as interview_router from talent.app import router as talent_router from candidate_forms.app import router as candidate_forms_router from g_sheet.app import router as g_sheet_router from s3.app import router as s3_router from department.app import router as department_router from verification_check.app import router as verification_check_router logging.basicConfig(level=logging.INFO,format="%(levelname)-8s %(name)s: %(message)s") logger=logging.getLogger("main") @asynccontextmanager async def lifespan(app): async with db_lifespan(app): broker_ready=False cv_broker_ready=False sheet_broker_ready=False llm_ready=False agent_ready=False close_llm=None close_agent=None broker=None cv_broker=None sheet_broker=None try: from taskiq_management.broker_setup import broker as _broker broker=_broker await broker.startup() broker_ready=True except Exception as exc: logger.warning("taskiq broker startup skipped: %s",exc) try: from taskiq_management.cv_broker_setup import cv_broker as _cv_broker cv_broker=_cv_broker await cv_broker.startup() cv_broker_ready=True except Exception as exc: logger.warning("taskiq cv broker startup skipped: %s",exc) try: from taskiq_management.g_sheet_broker_setup import sheet_broker as _sheet_broker sheet_broker=_sheet_broker await sheet_broker.startup() sheet_broker_ready=True except Exception as exc: logger.warning("taskiq sheet broker startup skipped: %s",exc) try: from llm_setup import init_llm,close_llm as _close_llm from agent.agent_setup import init_agent,close_agent as _close_agent close_llm=_close_llm close_agent=_close_agent await init_llm() llm_ready=True await init_agent() agent_ready=True except Exception as exc: logger.warning("llm/agent startup skipped: %s",exc) try: yield finally: if agent_ready and close_agent is not None: await close_agent() # Before close_llm(): the classifier holds a reference to the shared client, # which close_llm() disposes. No init counterpart — get_classifier() is lazy. try: from inbox_classifier.agent_setup import close_classifier close_classifier() except Exception as exc: logger.warning("classifier close skipped: %s",exc) try: from summary_gate.agent_setup import close_gate close_gate() except Exception as exc: logger.warning("summary gate close skipped: %s",exc) if llm_ready and close_llm is not None: await close_llm() if sheet_broker_ready and sheet_broker is not None: await sheet_broker.shutdown() if cv_broker_ready and cv_broker is not None: await cv_broker.shutdown() if broker_ready and broker is not None: await broker.shutdown() app=FastAPI(lifespan=lifespan) app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) @app.get("/health") async def health(): # Liveness only — no DB. Compose healthchecks and load balancers hit this. return JSONResponse(content={"status":"ok","status_code":200}) app.include_router(inbox_router) app.include_router(users_router) app.include_router(role_router) app.include_router(forget_password_router) app.include_router(confirmation_router) app.include_router(candidate_router) app.include_router(analytics_router) app.include_router(reports_router) app.include_router(offer_router) app.include_router(tasks_router) app.include_router(assessments_router) app.include_router(org_settings_router) app.include_router(saved_search_router) app.include_router(search_router) app.include_router(interview_router) app.include_router(talent_router) app.include_router(candidate_forms_router) app.include_router(g_sheet_router) app.include_router(s3_router) app.include_router(department_router) app.include_router(verification_check_router)