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

GPL-3.0-or-later.

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.2.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.2-py3-none-any.whl (80.3 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: gpodder_fastapi_router-0.1.2.tar.gz
  • Upload date:
  • Size: 61.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.8 {"installer":{"name":"uv","version":"0.11.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for gpodder_fastapi_router-0.1.2.tar.gz
Algorithm Hash digest
SHA256 50b8485c8862ac5f11be09945d31f393bab528e967e73747eec474171d02411d
MD5 3f1a645b5f5fdd8a967adc0350477b80
BLAKE2b-256 cc415c51c8cab4bc3fcc59aa9dbf356580281671f73c76963d113fc56bd37a08

See more details on using hashes here.

File details

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

File metadata

  • Download URL: gpodder_fastapi_router-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 80.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.8 {"installer":{"name":"uv","version":"0.11.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for gpodder_fastapi_router-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 634e3f3204d92dd938834d854ab6132df6550d69192462fa86a506ed7c172287
MD5 bd5deb24291d864737f05af690981262
BLAKE2b-256 f1c0560bba4c27ea2daa533f104a5aea77bd28273010051579554c6c16c99f51

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