morethanadiagnosis-hub/backend/app/api/v1/podcast.py
2025-11-19 09:42:15 -08:00

84 lines
2.5 KiB
Python

from fastapi import APIRouter, HTTPException
import feedparser
import httpx
from pydantic import BaseModel
from typing import List, Optional
from datetime import datetime
router = APIRouter()
RSS_FEED_URL = "https://rss.libsyn.com/shows/563180/destinations/4867845.xml"
class PodcastEpisode(BaseModel):
id: str
title: str
description: str
audio_url: str
published_at: str
duration: Optional[str] = None
image_url: Optional[str] = None
class PodcastFeed(BaseModel):
title: str
description: str
image_url: Optional[str] = None
episodes: List[PodcastEpisode]
@router.get("/", response_model=PodcastFeed)
async def get_podcasts():
try:
async with httpx.AsyncClient() as client:
response = await client.get(RSS_FEED_URL)
response.raise_for_status()
rss_content = response.text
feed = feedparser.parse(rss_content)
if feed.bozo:
# Log warning but try to proceed if possible, or raise error
print(f"Warning: Feed parsing error: {feed.bozo_exception}")
episodes = []
for entry in feed.entries:
# Extract audio URL
audio_url = ""
for link in entry.links:
if link.type == "audio/mpeg":
audio_url = link.href
break
if not audio_url:
continue # Skip episodes without audio
# Extract image
image_url = None
if 'image' in entry:
image_url = entry.image.href
elif 'itunes_image' in entry:
image_url = entry.itunes_image.href
episodes.append(PodcastEpisode(
id=entry.id,
title=entry.title,
description=entry.summary,
audio_url=audio_url,
published_at=entry.published,
duration=entry.get('itunes_duration'),
image_url=image_url
))
feed_image = None
if 'image' in feed.feed:
feed_image = feed.feed.image.href
elif 'itunes_image' in feed.feed:
feed_image = feed.feed.itunes_image.href
return PodcastFeed(
title=feed.feed.title,
description=feed.feed.description,
image_url=feed_image,
episodes=episodes
)
except Exception as e:
raise HTTPException(status_code=500, detail=f"Failed to fetch podcasts: {str(e)}")