Your tool for handling audiobook requests on a Plex/Audiobookshelf/Jellyfin instance.
If you've heard of Overseer, Ombi, or Jellyseer; this is in the similar vein, but for audiobooks.
Table of Contents
Getting Started
AudioBookRequest is intended to be deployed using Docker or Kubernetes. For "bare-metal" deployments, head to the local development section.
Quick Start
Run the image directly:
docker run -p 8000:8000 -v $(pwd)/config:/config markbeep/audiobookrequest:1
Then head to http://localhost:8000.
Usage
- Logging in the first time the login-type and root admin user has to be configured.
- Head to
Settings>Usersto create accounts for your friends. - Any user can search for books and request them by clicking the
+button. - The admin can head to the wishlist to see all the books that have been requested.
Auto download
Auto-downloading enables requests by Trusted and Admin users to directly start downloading once requested.
- Ensure your Prowlarr instance is correctly set up with any indexers and download clients you want. More info.
- On Prowlarr, head to
Settings>Generaland copy theAPI Key. - On AudioBookRequest, head to
Settings>Prowlarrand enter the API key as well as the base URL of your Prowlarr instance, i.e.https://prowlarr.example.com. - Head to
Settings>Downloadto configure the automatic download settings:- Enable
Auto Downloadat the top. - The remaining heuristics determine the ranking of any sources retrieved from Prowlarr.
- Indexer flags allow you to add priorities to certain sources like freeleeches.
- Enable
Notifications
Notifications depend on Apprise.
- Ensure you have a working Apprise instance.
- On Apprise, create a new configuration. For example paste your Discord webhook link (
https://discord.com/api/webhooks/<channel>/<id>) into the configuration. - On Apprise, copy the notification url along the format of
https://apprise.example.com/notify/<id>. - On AudioBookRequest, head to
Settings>Notificationsand add the URL. - Configure the remaining settings. The event variables are case sensitive.
OpenID Connect
OIDC allows you to use an external authentication service (Authentik, Keycloak, etc.) for user and group authentication. It can be configured in Settings>Security. The following six settings are required to successfully set up oidc. Ensure you use the correct values. Incorrect values or changing values on your authentication server in the future can cause lead to locking you out of the service. In those cases head to Getting "locked" out.
well-knownconfiguration endpoint: This is located at/realms/{realm-name}/.well-known/openid-configurationfor keycloak or/application/o/{issuer}/.well-known/openid-configurationfor authentik.- username claim: The claim that should be used for usernames. The username has to be unique. NOTE: Any user logging in with the username of the root admin account will be root admin, no matter what group they're assigned.
- group claim: This is the claim that contains the group of each user. It should either be a string or a list of strings with one of the following case-insensitive values:
untrusted,trusted, oradmin. Any user without any groups is assigned theuntrustedrole. - scope: The scopes required to get all the necessary information. The scope
openidis almost always required. You need to add all required scopes to that the username and group claim is available. - client id
- client secret
In your auth server settings, make sure you allow for redirecting to /auth/oidc. The oidc-login flow will redirect you there after you log in. Additionally, the access token expiry time from the authentication server will be used if provided. This might be fairly low by default.
Applying settings does not directly invalidate your current session. To test OIDC-settings, press the "log out" button to invalidate your current session.
Getting locked out
In the case of an OIDC misconfiguration, i.e. changing a setting like your client secret on your auth server, can cause you to be locked out. In these cases, you can head to /login?backup=1, where you can log in using your root admin credentials allowing you to correctly configure any settings.
Alternative Deployments
Docker image is located on dockerhub.
NOTE: It is not recommended to use :latest in case of incompatible changes that are not backwards compatible. For versioning, SemVer is used.
For experimental builds (latest commits to main), the :nightly version can be used.
Docker compose
services:
web:
image: markbeep/audiobookrequest:1
ports:
- "8000:8000"
volumes:
- ./config:/config
Kubernetes
apiVersion: apps/v1
kind: Deployment
metadata:
name: audiobookrequest
labels:
app: audiobookrequest
spec:
replicas: 1
selector:
matchLabels:
app: audiobookrequest
template:
metadata:
labels:
app: audiobookrequest
spec:
containers:
- name: audiobookrequest
image: markbeep/audiobookrequest:1
imagePullPolicy: Always
volumeMounts:
- mountPath: /config
name: abr-config
ports:
- name: http-request
containerPort: 8000
volumes:
- name: abr-config
hostPath:
path: /mnt/disk/AudioBookRequest/
Environment Variables
| ENV | Description | Default |
|---|---|---|
ABR_APP__PORT |
The port to run the server on. | 8000 |
ABR_APP__DEBUG |
If to enable debug mode. Not recommended for production. | false |
ABR_APP__OPENAPI_ENABLED |
If set to true, enables an OpenAPI specs page on /docs. |
false |
ABR_APP__CONFIG_DIR |
The directory path where persistant data and configuration is stored. If ran using Docker or Kubernetes, this is the location a volume should be mounted to. | /config |
ABR_APP__LOG_LEVEL |
One of DEBUG, INFO, WARN, ERROR. |
INFO |
ABR_APP__BASE_URL |
Defines the base url the website is hosted at. If the website is accessed at example.org/abr/, set the base URL to /abr/ |
|
ABR_DB__SQLITE_PATH |
If relative, path and name of the sqlite database in relation to ABR_APP__CONFIG_DIR. If absolute (path starts with /), the config dir is ignored and only the absolute path is used. |
db.sqlite |
Contributing
Suggestions are always welcome. Do note though that a big goal is to keep this project on a smaller scale. The main focus of this project is to make it easy for friends to request and potentially automatically download Audiobooks without having to give direct access to Readarr/Prowlarr. It might make sense to first create an issue before undertaking a big project and opening a pull request. Your idea could already be worked on in the background.
Local Development
Virtual environments help isolate any installed packages to this directory. Project was made with Python 3.12 and uses new generics introduced in 3.12. Older python versions might not work or could have incorrect typing.
For improved dependency management, uv is used instead of pip.
# This creates the venv as well as installs all dependencies
uv sync
For local development, environment variables can be added to .env.local and they'll be used wherever required.
Initialize Database
Alembic is used to create database migrations. Run the following before starting up the application for the first time. It will initialize the directory if non-existant, create the database file as well as execute any required migrations.
uv run alembic upgrade heads
In case of any model changes, remember to create migrations using alembic revision --autogenerate -m "<message>".
Running
Running the application is best done in multiple terminals:
- Start FastAPI dev mode:
uv run fastapi dev
Website can be visited at http://localhost:8000.
- Install daisyUI and start Tailwindcss watcher. Required for any CSS styling.
npm i
uv run tailwindcss -i static/tw.css -o static/globals.css --watch
# Alternatively npx can be used to run tailwindcss
npx @tailwindcss/cli@4 -i static/tw.css -o static/globals.css --watch
- Optional: Start browser-sync. This hot reloads the website when the html template or python files are modified:
browser-sync http://localhost:8000 --files templates/** --files app/**
NOTE: Website has to be visited at http://localhost:3000 instead.
Docker Compose
The docker compose can also be used to run the app locally:
docker compose up --build
