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

Uploaded Python 3

File details

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

File metadata

  • Download URL: gpodder_fastapi_router-0.1.1.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.1.tar.gz
Algorithm Hash digest
SHA256 d764dd719ae8e405bd008bbce42465781b3bd98c2ade6bcde80f001de523f9f6
MD5 ff419735435d8ec046f3b802438e5b91
BLAKE2b-256 d53ca610c3b4e35cfbddc264e4d416672640af11ae9137facb832b58b8b30833

See more details on using hashes here.

File details

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

File metadata

  • Download URL: gpodder_fastapi_router-0.1.1-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.1-py3-none-any.whl
Algorithm Hash digest
SHA256 30cb56c4d54fef82af775785ae768bbeb5329984905cee3996473f8dc844e368
MD5 f4a22f21dc959777716cd1e8cf050735
BLAKE2b-256 2fce5edc385860888767595687ce3de1147b5d8412d3b9879f32507d7e649c0a

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