from fastapi import FastAPI, BackgroundTasks from pydantic import BaseModel import httpx from bs4 import BeautifulSoup import asyncio from datetime import datetime, timedelta app = FastAPI() class Notice(BaseModel): name: str link: str # URL of the notice list page url = 'https://www.durguniversity.ac.in/index.php/Home/Noticelist' # Cache to store notices and the last updated timestamp cache = { "notices": [], "last_updated": None } CACHE_TTL = timedelta(minutes=5) # Cache Time-to-Live (5 minutes) async def fetch_notices(): """Fetch notices from the website and update the cache.""" async with httpx.AsyncClient() as client: response = await client.get(url) if response.status_code != 200: print(f"Failed to retrieve content. Status code: {response.status_code}") return # Parse the HTML content using a faster parser like 'lxml' soup = BeautifulSoup(response.text, 'lxml') rows = soup.select('td a') # Directly target tags inside # Process notices notice_list = [] seen_links = set() for link_tag in rows: notice_link = link_tag.get('href', '').strip() notice_name = link_tag.text.strip() if notice_link and notice_link not in seen_links: seen_links.add(notice_link) notice_name = notice_name or f"Notice {len(notice_list) + 1}" notice_list.append({'name': notice_name, 'link': notice_link}) # Update the cache cache["notices"] = notice_list[:50] # Store top 50 notices cache["last_updated"] = datetime.utcnow() print("Cache updated.") @app.on_event("startup") async def startup_event(): """Schedule the cache refresh task on application startup.""" asyncio.create_task(cache_refresh_task()) async def cache_refresh_task(): """Background task to refresh cache periodically.""" while True: await fetch_notices() await asyncio.sleep(CACHE_TTL.total_seconds()) @app.get("/notices", response_model=list[Notice]) async def get_notices(): """Serve notices from the cache.""" if cache["last_updated"] and datetime.utcnow() - cache["last_updated"] < CACHE_TTL: # Serve cached data if it's still valid return cache["notices"] # If cache is expired or unavailable, fetch notices live await fetch_notices() return cache["notices"]