podcast_helper.api module
Podcast Helper — FastAPI HTTP surface.
Exposes every public function in podcast_helper as an HTTP
endpoint so podcast-helper can be dropped behind any reverse proxy
and consumed by other services. Kept intentionally minimal:
/feedand/latest: JSON responses over an RSS / Atom URL./probe: JSON classification of any URL (file / direct / rss / yt-dlp-<extractor>) — invaluable for operators debugging podcast ingest./stream: chunkedStreamingResponseof raw f32le PCM bytes for any audio-bearing URL. Downstream ASR services can pipe the response directly./record: server-side archive to a compressed file, returned viaFileResponse; the temp file is cleaned up by aBackgroundTaskonce the response has been fully streamed to the client./gui(and/which redirects to it): a self-contained single-page episode browser (Tailwind CDN + vanilla JS) that drives the very same/feed//probe//recordendpoints — no extra server logic.
Install the extra to get the runtime dependencies:
pip install 'podcast-helper[api]'
Then run the app with any ASGI server:
uvicorn podcast_helper.api:app --host 0.0.0.0 --port 8000
Usage Example
>>> # Start the server:
>>> # uvicorn podcast_helper.api:app --reload
>>> # List a feed's episodes:
>>> # curl 'http://localhost:8000/feed?url=https://feeds.npr.org/510289/podcast.xml'
>>> # Get the latest episode:
>>> # curl 'http://localhost:8000/latest?url=https://feeds.npr.org/510289/podcast.xml'
>>> # Archive a URL to disk (server-side ffmpeg):
>>> # curl -o ep.mp3 -X POST -F 'url=…' -F 'output_format=mp3' \
>>> # http://localhost:8000/record
>>> # Full OpenAPI docs at http://localhost:8000/docs
- podcast_helper.api.get_feed(url=fastapi.Query, max_episodes=fastapi.Query)
Return the feed’s episodes as JSON (most-recent first).
- podcast_helper.api.get_latest(url=fastapi.Query)
Return the latest episode (with a non-empty audio enclosure) as JSON.
- Parameters:
url (str)
- Return type:
fastapi.responses.JSONResponse
- podcast_helper.api.gui()
Serve the self-contained single-page ‘episode browser’ GUI.
The page (defined in
podcast_helper.gui) is a build-step-free HTML + Tailwind-CDN + vanilla-JS client that calls the very same/feed//probe//recordendpoints defined below. It adds no server-side logic — it is purely a friendlier front door to the API.- Returns:
The complete HTML document (status 200,
text/html).- Return type:
HTMLResponse
- podcast_helper.api.health()
Simple liveness probe — no dependency check, just proves the app is up.
- Return type:
- podcast_helper.api.probe(url=fastapi.Query, show_url=fastapi.Query)
Report how podcast-helper classified a URL (source_kind, is_live, headers).
- async podcast_helper.api.record(background, url=fastapi.Form, output_format=fastapi.Form, sample_rate=fastapi.Form, mono=fastapi.Form, frame_ms=fastapi.Form, speed=fastapi.Form)
Archive any audio-bearing URL to a compressed file server-side, then return the file as the response body.
- podcast_helper.api.root()
Redirect the bare root to the GUI so opening the server just works.
- Return type:
fastapi.responses.RedirectResponse
- podcast_helper.api.stream(url=fastapi.Form, sample_rate=fastapi.Form, mono=fastapi.Form, frame_ms=fastapi.Form, speed=fastapi.Form)
Stream raw f32le PCM for any audio-bearing URL.
Clients: pipe the response body into ffplay / a VAD / an ASR frontend. The Content-Type is
application/octet-stream; sample rate / channels / format are conveyed via headers below.