podcast_helper.feed module

podcast_helper.feed

Lightweight RSS / Atom feed reader for podcasts. Returns episodes in a homogeneous Episode shape regardless of feed flavour (iTunes extensions, Atom, Podcasting 2.0).

Uses podcastparser as primary parser (podcast-aware: iTunes extensions, transcripts, chapters URL), with a feedparser fallback for feeds podcastparser refuses (unusual Atom variants).

Public surface

  • Episode — typed dict (guid, title, enclosure_url, …)

  • feed() — return episodes ordered most-recent first (via published_at)

  • latest_episode() — convenience for the first non-empty enclosure

Author

Warith HARCHAOUI — https://linkedin.com/in/warith-harchaoui

class podcast_helper.feed.Episode[source]

Bases: TypedDict

One podcast episode, normalised across feed flavours.

Keys

guidstr

Stable episode identifier (RSS <guid> or yt-dlp-style fallback). Empty string if the feed didn’t ship one.

titlestr

Episode title.

descriptionstr

Long-form description / show notes. May contain HTML.

linkstr

Episode webpage / show notes URL (NOT the audio URL).

published_atstr

ISO 8601 timestamp (YYYY-MM-DDTHH:MM:SS+00:00 UTC). Empty string if not provided.

duration_secondsint

Reported duration. 0 when missing.

enclosure_urlstr

Direct audio URL (the actual media file). This is what you feed to podcast_helper.extract_audio_stream().

enclosure_typestr

MIME type of the enclosure ("audio/mpeg", "audio/x-m4a", …).

enclosure_size_bytesint

Reported file size of the enclosure. 0 when missing.

image_urlstr

Episode-level cover art URL; falls back to the show’s image.

description: str
duration_seconds: int
enclosure_size_bytes: int
enclosure_type: str
enclosure_url: str
guid: str
image_url: str
published_at: str
title: str
podcast_helper.feed.feed(url, *, max_episodes=None)[source]

Fetch an RSS / Atom podcast feed and return its episodes.

Episodes are sorted most recent first by published_at (ISO); episodes without a parseable date sink to the bottom but keep their relative order.

Parameters:
  • url (str) – Feed URL (RSS or Atom).

  • max_episodes (int, optional) – Cap the number of episodes returned. None (default) returns everything the feed advertises.

Returns:

Possibly empty if the feed has no episodes / no audio enclosures.

Return type:

list[Episode]

Raises:
  • requests.HTTPError – If the GET request returns a non-2xx status.

  • RuntimeError – If neither podcastparser nor feedparser could extract any episode (genuinely broken feed).

podcast_helper.feed.latest_episode(url)[source]

Return the most recent episode of a podcast feed with a non-empty audio enclosure URL.

Convenience around feed() for the common “I just want the latest” case. Skips items without an audio enclosure (some feeds publish text-only “trailer” items).

Parameters:

url (str) – Feed URL.

Return type:

Episode

Raises:
  • requests.HTTPError – If the GET request returns a non-2xx status.

  • RuntimeError – If the feed parses but no episode has an audio enclosure.