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.3.tar.gz (65.1 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.3-py3-none-any.whl (82.7 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: gpodder_fastapi_router-0.1.3.tar.gz
  • Upload date:
  • Size: 65.1 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.3.tar.gz
Algorithm Hash digest
SHA256 3daa43de229d4dad383f768b9cc1d7988d4dde5d6a88899900a5b0d1287ebdd1
MD5 d0d8c91b2a0fe3c5bc20dbac77af8cc1
BLAKE2b-256 7c4239dfe212504a92b64a69734a45e037b06197c5f8402515a8d4b578c32a8d

See more details on using hashes here.

File details

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

File metadata

  • Download URL: gpodder_fastapi_router-0.1.3-py3-none-any.whl
  • Upload date:
  • Size: 82.7 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.3-py3-none-any.whl
Algorithm Hash digest
SHA256 2eb2a780df1306f1b321b5c28106f2730ec2572574fa4b5df649bdf5e46c6f91
MD5 3eecf3f28f3adb7ce33e372aa14440a1
BLAKE2b-256 98aaa8af7586271dd665a646fe10b0f45cc5c166130b903a1ea712664f5a8218

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