Skip to content

ArchiveLabs/opds.openlibrary.org

Repository files navigation

opds.openlibrary.org

A stand-alone, dockerized FastAPI service that implements an OPDS 2.0 feed for Open Library, backed by pyopds2_openlibrary.


Project structure

app/
  main.py              # FastAPI app + exception handlers
  logger.py            # Central logging factory (stdout only)
  config/
    __init__.py        # Media types, env vars, featured subjects
  exceptions/
    __init__.py        # OPDSException, EditionNotFound, UpstreamError
  routes/
    opds.py            # All route handlers (/, /search, /books/*)
docker/
  Dockerfile           # Docker image definition
  docker-compose.yml   # Compose service definition
scripts/
  configure.sh         # Generates .env from defaults

Endpoints

Interactive docs: /docs (Swagger UI) · /redoc


Prerequisites

  • Docker + Docker Compose — for the recommended Docker workflow
  • Python 3.12+ — only needed for local development without Docker

Alternatively Podman can be used. In that case, aardvark-dns is required.


Quick start (Docker — recommended)

1. Clone the repo

git clone https://github.com/ArchiveLabs/opds.openlibrary.org.git
cd opds.openlibrary.org

2. Configure environment

./scripts/configure.sh

This creates a .env file with sensible defaults. Edit it to override any values before starting the service.

3. Build and start

docker compose up --build

The service is available at http://localhost:8080.

To run in the background:

docker compose up --build -d

4. Stop the service

docker compose down

Environment variables

Managed via .env (generated by configure.sh). All are optional.

Variable Default Description
OPDS_BASE_URL (falls back to request base URL) Public URL of this OPDS service, used in self-referencing links. When unset, the base URL is inferred from each incoming request (suitable for local dev). Set this when running behind a reverse proxy.
OL_BASE_URL https://openlibrary.org OpenLibrary backend URL for API calls and alternate links.
OL_USER_AGENT OPDSBot/1.0 (opds.openlibrary.org; opds@openlibrary.org) User-Agent sent with every request to OpenLibrary.
OL_REQUEST_TIMEOUT 30.0 Timeout in seconds for requests to the OpenLibrary API.

Running locally (without Docker)

# 1. Create and activate a virtual environment
python -m venv env
source env/bin/activate   # Windows: env\Scripts\activate

# 2. Install dependencies
pip install -r requirements.txt

# 3. Start the server
uvicorn app.main:app --reload --port 8080

Testing the endpoints

# Homepage catalog
curl -s http://localhost:8080/ | python -m json.tool | head -30

# Search
curl -s "http://localhost:8080/search?query=Python&limit=5" | python -m json.tool | head -30

# Single edition
curl -s http://localhost:8080/books/OL7353617M | python -m json.tool | head -30

# 404 — non-existent edition
curl -s http://localhost:8080/books/OL0000000M
# → {"detail": "Edition not found: OL0000000M"}

Running automated tests

pip install pytest httpx
pytest -v

All tests are offline — network calls to OpenLibrary are mocked.


Error responses

Exception HTTP status Cause
EditionNotFound 404 Edition OLID not found in OpenLibrary
UpstreamError 502 OpenLibrary returned an error or is unreachable

All errors are logged to stdout by the service logger.

About

Experimental OPDS standalone FastAPI Server

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors