Created
December 10, 2024 12:09
-
-
Save adgedenkers/bdae83274148404e688d0062931696ff to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# ----------------------------------------------------------------------------- | |
# List sports schedules | |
# ----------------------------------------------------------------------------- | |
async def fetch_schedule_data() -> List[Dict[str, Any]]: | |
""" | |
Asynchronously fetch and parse the sports schedule data. | |
""" | |
url = "https://www.schedulegalaxy.com/schools/159/teams/58255" | |
params = { | |
"commit": "Filter+activities", | |
"game_types[]": [ | |
"scrimmage", | |
"regular_season", | |
"post_season", | |
"practice", | |
"non_district", | |
"district" | |
], | |
"load_partial": "1", | |
"type": "", | |
"utf8": "✓", | |
"_": "1732193986589" | |
} | |
try: | |
async with aiohttp.ClientSession() as session: | |
async with session.get(url, params=params) as response: | |
if response.status != 200: | |
raise HTTPException( | |
status_code=response.status, | |
detail="Failed to fetch schedule data from external service" | |
) | |
html_content = await response.text() | |
# Parse the HTML content | |
soup = BeautifulSoup(html_content, 'html.parser') | |
today_date = datetime.now().strftime("%b %d, %Y") | |
# Find the table | |
table = soup.find('table', class_='schedule') | |
if not table: | |
return [] | |
rows = table.find('tbody').find_all('tr') if table.find('tbody') else [] | |
# Extract the data for today's date | |
schedule = [] | |
for row in rows: | |
date_cell = row.find('td') | |
if not date_cell: | |
continue | |
date_text = date_cell.get_text() | |
date_text = date_text.replace('\n', ' ').strip() | |
from fastapi.responses import JSONResponse | |
if today_date in date_text: | |
cells = row.find_all('td') | |
if len(cells) >= 10: # Ensure we have all required cells | |
data = { | |
"date": today_date, | |
"type": cells[1].get_text(strip=True), | |
"opponents": cells[2].get_text(strip=True), | |
"start_time": cells[3].get_text(strip=True), | |
"end_time": cells[4].get_text(strip=True), | |
"location": cells[5].get_text(strip=True), | |
"departure": cells[6].get_text(strip=True), | |
"transportation": cells[7].get_text(strip=True), | |
"league_non_league": cells[8].get_text(strip=True), | |
"notes": cells[9].get_text(strip=True), | |
"details_url": row.find('a')['href'] if row.find('a') else None | |
} | |
schedule.append(data) | |
#return JSONResponse(content=schedule, media_type="application/json", indent=4) | |
return schedule | |
except aiohttp.ClientError as e: | |
logger.error(f"Network error while fetching schedule: {str(e)}") | |
raise HTTPException( | |
status_code=503, | |
detail="External service temporarily unavailable" | |
) | |
except Exception as e: | |
logger.error(f"Error fetching schedule: {str(e)}") | |
raise HTTPException( | |
status_code=500, | |
detail="Internal server error while fetching schedule" | |
) | |
#@app.get("/sports/schedule", tags=["Sports"]) | |
@app.get("/bball_schedule") | |
async def get_sports_schedule(): | |
""" | |
Get today's sports schedule. This endpoint is publicly accessible and requires no authentication. | |
Returns: | |
List of today's scheduled activities including game type, opponents, times, location, etc. | |
""" | |
try: | |
schedule = await fetch_schedule_data() | |
return { | |
"status": "success", | |
"timestamp": datetime.utcnow().isoformat(), | |
"schedule": schedule | |
} | |
except HTTPException: | |
raise | |
except Exception as e: | |
logger.error(f"Unexpected error in get_sports_schedule: {str(e)}") | |
raise HTTPException( | |
status_code=500, | |
detail="An unexpected error occurred" | |
) | |
@app.get("/bball_schedule/display") | |
def serve_html_page(): | |
html_content = """ | |
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Today's Basketball</title> | |
<style> | |
body { | |
font-family: Arial, sans-serif; | |
margin: 0; | |
padding: 0; | |
background-color: #f8f9fa; | |
color: #333; | |
} | |
.container { | |
max-width: 800px; | |
margin: 50px auto; | |
padding: 20px; | |
background: #fff; | |
border-radius: 8px; | |
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); | |
} | |
h1 { | |
text-align: center; | |
color: #0056b3; | |
margin-bottom: 20px; | |
} | |
table { | |
width: 100%; | |
border-collapse: collapse; | |
margin: 20px 0; | |
} | |
th, td { | |
padding: 10px; | |
text-align: left; | |
border: 1px solid #ddd; | |
} | |
th { | |
background-color: #f4f4f4; | |
font-weight: bold; | |
} | |
tr:nth-child(even) { | |
background-color: #f9f9f9; | |
} | |
tr:hover { | |
background-color: #f1f1f1; | |
} | |
.empty { | |
text-align: center; | |
margin-top: 20px; | |
color: #888; | |
font-style: italic; | |
} | |
</style> | |
</head> | |
<body> | |
<div class="container"> | |
<h1>Today's Basketball</h1> | |
<div id="schedule-output">Loading schedule...</div> | |
</div> | |
<script> | |
// Fetch the basketball schedule data | |
fetch('/bball_schedule') | |
.then(response => { | |
if (!response.ok) { | |
throw new Error(`HTTP error! Status: ${response.status}`); | |
} | |
return response.json(); | |
}) | |
.then(data => { | |
const schedule = data.schedule; | |
if (!schedule || schedule.length === 0) { | |
document.getElementById('schedule-output').innerHTML = | |
'<div class="empty">No schedule data available.</div>'; | |
return; | |
} | |
// Get the first schedule entry | |
const event = schedule[0]; | |
// Generate table rows for non-empty fields | |
const rows = Object.entries(event) | |
.filter(([key, value]) => value && typeof value === 'string') // Only non-empty strings | |
.map(([key, value]) => { | |
// Format the details_url as a clickable link | |
if (key === "details_url") { | |
value = `<a href="https://www.schedulegalaxy.com${value}" target="_blank">Details</a>`; | |
} | |
return ` | |
<tr> | |
<td>${key.replace(/_/g, ' ')}</td> | |
<td>${value}</td> | |
</tr> | |
`; | |
}) | |
.join(''); | |
// Render the table | |
const tableHTML = ` | |
<table> | |
<thead> | |
<tr> | |
<th colspan="2">Oxford Academy 8th Grade Boys Basketball</th> | |
</tr> | |
</thead> | |
<tbody> | |
${rows} | |
</tbody> | |
</table> | |
`; | |
document.getElementById('schedule-output').innerHTML = tableHTML; | |
}) | |
.catch(error => { | |
document.getElementById('schedule-output').innerHTML = | |
'Error loading schedule: ' + error.message; | |
}); | |
</script> | |
</body> | |
</html> | |
""" | |
return HTMLResponse(content=html_content, media_type="text/html") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment