Skip to main content

Pluggable FastAPI router that implements the gpodder.net (mygpo) HTTP API.

Project description

gpodder-fastapi-router

A pip-installable FastAPI router that implements the gpodder.net (mygpo) HTTP API, ready to drop into any FastAPI application. Bring your own database (SQLite or PostgreSQL via async SQLAlchemy 2).

Includes:

  • All mygpo 2.11 endpoints (auth, directory, devices, sync, subscriptions, episode actions, settings, lists, favorites, suggestions, clientconfig)
  • HTTP Basic and session-cookie auth (works with AntennaPod, gPodder, Podverse, …)
  • Admin dashboard at /dashboard — users, devices, subscriptions, stats
  • CLI for offline user management (gpodder-router create-user …)
  • Auto-generated OpenAPI docs at /docs and /redoc
  • See docs/ for the full handbook.

Install

uv add gpodder-fastapi-router            # core
uv add "gpodder-fastapi-router[sqlite]"  # + aiosqlite driver
uv add "gpodder-fastapi-router[postgresql]"  # + asyncpg driver

Requires Python >= 3.12.

Quick start

from fastapi import FastAPI
from gpodder_router import GPodderConfig, attach

app = FastAPI()
attach(
    app,
    config=GPodderConfig(
        database_url="sqlite+aiosqlite:///./gpodder.db",
        base_url="http://localhost:8000",
    ),
)

Run:

uv run uvicorn examples.simple_app:app --reload

Register a user, then point any gpodder-compatible client at the server:

curl -X POST http://localhost:8000/api/2/auth/alice/register.json \
     -H 'Content-Type: application/json' \
     -d '{"password": "secret"}'

Mounting under a prefix

attach(app, prefix="/gpodder")
# /gpodder/api/2/auth/{username}/login.json ...

Manual integration (no auto startup hooks)

from gpodder_router import Database, GPodderConfig, build_router

cfg = GPodderConfig()
db = Database(cfg.database_url)

app = FastAPI()
app.state.gpodder_config = cfg
app.state.gpodder_db = db
app.include_router(build_router())

@app.on_event("startup")
async def _init() -> None:
    await db.create_all()

Or use the bundled lifespan:

from gpodder_router import GPodderConfig, build_router, lifespan

cfg = GPodderConfig()
app = FastAPI(lifespan=lambda a: lifespan(a, config=cfg))
app.include_router(build_router())

Configuration

GPodderConfig is a pydantic-settings model. Values can be supplied inline or via GPODDER_* environment variables.

Field Env Default
database_url GPODDER_DATABASE_URL sqlite+aiosqlite:///./gpodder.db
create_tables GPODDER_CREATE_TABLES True
echo_sql GPODDER_ECHO_SQL False
allow_registration GPODDER_ALLOW_REGISTRATION True (extension endpoint)
base_url GPODDER_BASE_URL http://localhost:8000
feedservice_url GPODDER_FEEDSERVICE_URL http://localhost:8000/feedservice
update_timeout GPODDER_UPDATE_TIMEOUT 604800 (1 week)
bcrypt_rounds GPODDER_BCRYPT_ROUNDS 12

PostgreSQL example:

GPodderConfig(
    database_url="postgresql+asyncpg://gpodder:pw@localhost:5432/gpodder",
)

Implemented endpoints

All endpoints from mygpo OpenAPI 2.11:

Section Endpoints
Client Parametrization GET /clientconfig.json
Authentication POST /api/2/auth/{username}/login.json, .../logout.json, .../register.json*
Directory GET /api/2/tags/{count}.json, /api/2/tag/{tag}/{count}.json, /api/2/data/podcast.json, /api/2/data/episode.json, /toplist, /search
Suggestions GET /suggestions/{number}.{format}
Devices GET /api/2/devices/{username}.json, POST /api/2/devices/{username}/{deviceid}.json, GET /api/2/updates/{username}/{deviceid}.json
Device Sync GET/POST /api/2/sync-devices/{username}.json
Subscriptions (simple) GET/PUT /subscriptions/{username}/{deviceid}.{format}, GET /subscriptions/{username}.{format}
Subscriptions (advanced) POST/GET /api/2/subscriptions/{username}/{deviceid}.json
Episode Actions POST/GET /api/2/episodes/{username}.json
Settings GET/POST /api/2/settings/{username}/{scope}.json
Favorites GET /api/2/favorites/{username}.json
Podcast Lists GET /api/2/lists/{username}.json, POST /api/2/lists/{username}/create.{format}, GET/PUT/DELETE /api/2/lists/{username}/list/{listname}.{format}

* register.json is an extension on top of mygpo. Disable via GPodderConfig(allow_registration=False) to require server-side provisioning.

Supported response formats: json, xml, opml, txt, jsonp.

Directory / suggestions / favorites are stub-implemented (returning empty result sets) since a self-hosted server has no global directory. The schema is in place; populate the gpodder_favorites table or override the routers to plug in your own data sources.

Programmatic user management

from gpodder_router import Database, GPodderConfig
from gpodder_router.services import users as users_svc

cfg = GPodderConfig()
db = Database(cfg.database_url)
await db.create_all()
async with db.session() as s:
    await users_svc.create_user(s, username="alice", password="secret")

Authentication

HTTP Basic, exactly as mygpo. Passwords are stored as bcrypt hashes. Path-{username} is verified against the authenticated user; a mismatch returns 400, matching the upstream contract.

Dashboard

Mounted at /dashboard (toggle with enable_dashboard, change with dashboard_prefix). The first registered user is the bootstrap admin; in production set admin_usernames=["alice", ...]. See docs/dashboard.md.

CLI

gpodder-router create-user alice           # prompts for password
gpodder-router list-users
gpodder-router set-password alice
gpodder-router delete-user bob
gpodder-router init-db

Same operations also available as python -m gpodder_router …. See docs/cli.md.

Configuration files

Three ways to configure (priority highest → lowest):

  1. kwargsGPodderConfig(database_url=..., base_url=...)
  2. envGPODDER_* variables, optionally loaded from a .env file
  3. TOMLGPodderConfig.from_toml("config.toml") — see examples/config.toml
cp .env.example .env   # then edit

Docker

docker compose up -d                                 # SQLite
docker compose -f docker-compose.postgres.yml up -d  # PostgreSQL

Documentation

Live API docs once running:

  • http://localhost:8000/docs (Swagger UI)
  • http://localhost:8000/redoc (ReDoc)
  • http://localhost:8000/openapi.json

Development

uv sync --extra sqlite --group dev
uv run pytest
uv run uvicorn examples.simple_app:app --reload

License

AGPL-3.0-or-later, matching upstream mygpo.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

gpodder_fastapi_router-0.1.0.tar.gz (61.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

gpodder_fastapi_router-0.1.0-py3-none-any.whl (80.3 kB view details)

Uploaded Python 3

File details

Details for the file gpodder_fastapi_router-0.1.0.tar.gz.

File metadata

File hashes

Hashes for gpodder_fastapi_router-0.1.0.tar.gz
Algorithm Hash digest
SHA256 1f506cc5e0710e8be804841b61a87b22da8f8024397548a446ca7ef725aff4ba
MD5 e6d6dc09c2f00a144e64559378dcdb84
BLAKE2b-256 14806be01d043f24d707f1a6ad7b661d36a45c8f846c4c8c0eea898024a858fd

See more details on using hashes here.

File details

Details for the file gpodder_fastapi_router-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for gpodder_fastapi_router-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ac9a8399faceeadf6ec2d4e079b54002a0a6e59c2ce6172b3d2b21bb939f4b33
MD5 d2f2e3857ba9746b7ce98325642927da
BLAKE2b-256 b018c11ab806aa691c1622fd61941e427601b9de97de700f9706a7102fc43907

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page