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"]
|