from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware # Scheduler imports from contextlib import asynccontextmanager from scheduler.scheduler import scheduler from scheduler.task_registry import task_registry from scheduler.tasks.cijene_task import CijeneDataFetchTask from scheduler.tasks.cleanup_task import DatabaseCleanupTask # Routes imports from api.product_routes import router as product_router from api.receipt_routes import router as receipt_router from api.scrape_routes import router as scrape_router from api.cijene_routes import router as cijene_router from api.similarity_routes import router as similarity_router from api.geocoding_routes import router as geocoding_router @asynccontextmanager async def lifespan(app: FastAPI): # Register task classes task_registry.register_task_class("cijene_fetch", CijeneDataFetchTask) task_registry.register_task_class("database_cleanup", DatabaseCleanupTask) # Create task instances fetch_task = task_registry.create_task( "cijene_fetch", "daily_cijene_fetch", name="Daily Cijene Data Fetch" ) cleanup_task = task_registry.create_task( "database_cleanup", "daily_cleanup", name="Daily Database Cleanup", dependencies=["daily_cijene_fetch"] # Run after fetch ) # Schedule the job chain scheduler.add_daily_job( "daily_data_pipeline", ["daily_cijene_fetch", "daily_cleanup"], hour=16, minute=58 ) # Add event handlers async def job_completed_handler(job_id: str, results: dict): print(f"✅ Job {job_id} completed successfully!") async def job_failed_handler(job_id: str, results: dict): print(f"❌ Job {job_id} failed!") scheduler.register_event_handler('job_completed', job_completed_handler) scheduler.register_event_handler('job_failed', job_failed_handler) # Start scheduler scheduler.start() yield # Shutdown scheduler.stop() # Initialize FastAPI app = FastAPI(title="SupaKuna API", lifespan=lifespan) # CORS configuration app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], expose_headers=["*"] ) # Add routers app.include_router(product_router) app.include_router(receipt_router) app.include_router(scrape_router) app.include_router(cijene_router) app.include_router(similarity_router) app.include_router(geocoding_router) @app.get("/", tags=["Health"]) def health_check(): return {"status": "OK"}