import os import sys import logging from pathlib import Path from contextlib import asynccontextmanager # Add project root and local src to path to allow direct execution current_dir = Path(__file__).resolve().parent project_root = current_dir.parent.parent.parent.parent # d:\...pipeline sys.path.append(str(project_root)) sys.path.append(str(current_dir.parent)) # d:\...\rag-api # ── Configure logging BEFORE any imports that use loggers ──────────────────── logging.basicConfig( level=logging.INFO, format="%(asctime)s [%(levelname)s] %(name)s: %(message)s", datefmt="%H:%M:%S", force=True, ) # Suppress noisy third-party loggers logging.getLogger("httpx").setLevel(logging.WARNING) logging.getLogger("httpcore").setLevel(logging.WARNING) logging.getLogger("hf_xet").setLevel(logging.WARNING) logging.getLogger("huggingface_hub").setLevel(logging.WARNING) logging.getLogger("transformers").setLevel(logging.WARNING) logging.getLogger("FlagEmbedding").setLevel(logging.WARNING) logging.getLogger("sentence_transformers").setLevel(logging.WARNING) logging.getLogger("urllib3").setLevel(logging.WARNING) logger = logging.getLogger(__name__) from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from src.core.config import settings from src.api.routes import rag, analytics, interactions, accounts, news, auth, top_stories from src.infrastructure.database import init_db from src.api.dependencies import prewarm_models import threading import uvicorn @asynccontextmanager async def lifespan(app: FastAPI): # Startup logger.info("=" * 60) logger.info("ARKI AI RAG API — Pipeline v2.5 starting up") logger.info(f" LLM provider : {settings.LLM_PROVIDER}") logger.info(f" Reranker model : {settings.RERANKER_MODEL}") logger.info(f" Hybrid search : {settings.ENABLE_HYBRID_SEARCH}") logger.info(f" Jina Reader : {settings.ENABLE_JINA_READER}") logger.info(f" Jina Reranker : {settings.JINA_RERANKER_ENABLED}") logger.info(f" NewsAPI : {bool(settings.NEWSAPI_KEY and settings.NEWSAPI_KEY != 'your-newsapi-key-here')}") logger.info("=" * 60) init_db() yield # Shutdown pass app = FastAPI( title=settings.PROJECT_NAME, openapi_url=f"{settings.API_V1_STR}/openapi.json", lifespan=lifespan ) # Set all CORS enabled origins app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) app.include_router(rag.router, prefix=f"{settings.API_V1_STR}/rag", tags=["RAG"]) app.include_router(analytics.router, prefix=f"{settings.API_V1_STR}/analytics", tags=["Analytics"]) app.include_router(interactions.router, prefix=f"{settings.API_V1_STR}/interactions", tags=["Interactions"]) app.include_router(accounts.router, prefix=f"{settings.API_V1_STR}/accounts", tags=["Accounts"]) # Alias for registration convenience app.include_router(accounts.router, prefix=f"{settings.API_V1_STR}/users", tags=["Users"], include_in_schema=False) app.include_router(auth.router, prefix=f"{settings.API_V1_STR}/auth", tags=["Auth"]) app.include_router(news.router, prefix=f"{settings.API_V1_STR}/news", tags=["News"]) app.include_router(top_stories.router, prefix=f"{settings.API_V1_STR}", tags=["Top Stories"]) @app.get(f"{settings.API_V1_STR}/status") def get_status(): return {"status": "online", "message": "RAG API Service is operational"} @app.get("/") def read_root(): return {"message": "Welcome to the RAG API Service", "status": "online"} if __name__ == "__main__": # Start the server directly from this script # Use the app object directly for simplicity when running as main uvicorn.run(app, host="0.0.0.0", port=8000)