Skip to content

Instantly share code, notes, and snippets.

@adgedenkers
Created December 10, 2024 12:09
Show Gist options
  • Save adgedenkers/bdae83274148404e688d0062931696ff to your computer and use it in GitHub Desktop.
Save adgedenkers/bdae83274148404e688d0062931696ff to your computer and use it in GitHub Desktop.
# -----------------------------------------------------------------------------
# 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