Spaces:
Sleeping
Sleeping
| from fastapi import FastAPI | |
| from fastapi.middleware.cors import CORSMiddleware | |
| from app.core.config import settings | |
| from app.api.router import api_router | |
| app = FastAPI( | |
| title=settings.PROJECT_NAME, | |
| openapi_url=f"{settings.API_V1_STR}/openapi.json" | |
| ) | |
| # Set all CORS enabled origins | |
| from app.db.base import Base | |
| from app.db.session import engine | |
| from app.models.resume import Resume | |
| from app.models.score import ResumeScore | |
| from app.models.user import User | |
| # Create tables (Moved to startup event) | |
| # Base.metadata.create_all(bind=engine) | |
| import asyncio | |
| async def startup_event(): | |
| print("Server ready") | |
| async def load_models_background(): | |
| print("Models loading in background...") | |
| try: | |
| # 1. Initialize DB | |
| Base.metadata.create_all(bind=engine) | |
| print("Database initialized.") | |
| # Models will load lazily on usage, saving startup memory. | |
| # print("Loading Embedding Model...") | |
| # EmbeddingService().load_model() | |
| # print("Embedding Model loaded.") | |
| # print("Initializing Vector Store...") | |
| # FAISSStore().initialize() | |
| # print("Vector Store initialized.") | |
| # 2. Rebuild FAISS index from DB if needed (Stateless Recovery) | |
| from app.vectorstore.faiss_store import FAISSStore | |
| from app.services.embedding_service import EmbeddingService | |
| from app.db.session import SessionLocal | |
| faiss_store = FAISSStore() | |
| faiss_store.initialize() | |
| db = SessionLocal() | |
| try: | |
| db_resumes = db.query(Resume).all() | |
| if db_resumes: | |
| print(f"Startup check: Found {len(db_resumes)} resumes in database.") | |
| unique_faiss_resumes = faiss_store.get_all_resumes() | |
| unique_faiss_ids = {r.get("resume_id") for r in unique_faiss_resumes if r.get("resume_id")} | |
| missing_resumes = [r for r in db_resumes if r.resume_id not in unique_faiss_ids] | |
| if missing_resumes: | |
| print(f"Rebuilding FAISS index: {len(missing_resumes)} resumes are missing from the FAISS store. Indexing...") | |
| embedding_service = EmbeddingService() | |
| embedding_service.load_model() | |
| for resume in missing_resumes: | |
| if resume.extracted_text: | |
| print(f"Generating embeddings and indexing resume: {resume.filename} (v{resume.version_number})") | |
| embeddings = embedding_service.generate_embeddings(resume.extracted_text) | |
| base_metadata = { | |
| "source": resume.filepath, | |
| "page_count": 0, | |
| "author": None, | |
| "creation_date": None, | |
| "producer": None, | |
| "resume_id": resume.resume_id, | |
| "filename": resume.filename, | |
| "filepath": resume.filepath, | |
| "version": resume.version_number, | |
| } | |
| metadatas = [base_metadata] * len(embeddings) | |
| faiss_store.add_vectors(embeddings, metadatas) | |
| print("FAISS index rebuild completed successfully.") | |
| else: | |
| print("Startup check: FAISS index is fully in sync with database.") | |
| else: | |
| print("Startup check: No resumes found in database.") | |
| except Exception as e: | |
| print(f"FAISS startup rebuild failed: {e}") | |
| finally: | |
| db.close() | |
| except Exception as e: | |
| print(f"Startup initialization failed (non-critical, retrying or continuing): {e}") | |
| # Schedule the task to run in the background | |
| asyncio.create_task(load_models_background()) | |
| # Set all CORS enabled origins | |
| origins = [ | |
| "http://localhost:3000", | |
| "http://127.0.0.1:3000", | |
| "http://localhost:3001", | |
| "http://127.0.0.1:3001", | |
| ] | |
| # Append dynamic CORS origins from environment config | |
| if settings.BACKEND_CORS_ORIGINS: | |
| for origin in settings.BACKEND_CORS_ORIGINS: | |
| origin_str = str(origin).rstrip("/") | |
| if origin_str not in origins: | |
| origins.append(origin_str) | |
| app.add_middleware( | |
| CORSMiddleware, | |
| allow_origins=origins, | |
| allow_credentials=True, | |
| allow_methods=["*"], | |
| allow_headers=["*"], | |
| ) | |
| app.include_router(api_router, prefix=settings.API_V1_STR) | |