A REST server to host, tag, and search images.
- Upload, serve, list, and delete images via REST API
- Content-based deduplication of uploads
- Tag images with lowercase keywords, search by tags (AND logic)
- List all tags in use across uploads
- Auto-generated JPEG thumbnails
- Pagination on list and search endpoints
- Optional webhook notifications on new uploads
- HTTP Basic authentication
- OpenAPI documentation at
/docs
This project is built with
Pythonas the programming languageuvas the Python package managerFastAPIas the web frameworkSQLModelas an ORMalembicfor database migrationspytestas the testing frameworkruffas a formatterpre-commitfor automatic execution of checks
Before starting the server, one needs to configure several options. For that, take the .env.example file
and copy it to .env:
cp .env.example .envAfterward, look into it and modify accordingly.
You at least want to change the username and password for server access.
MAX_UPLOAD_BYTES caps the size of a single uploaded file. The server rejects
larger requests with HTTP 413. Defaults to 25 MiB (26214400 bytes) when unset.
Lenzr can notify an external service when a new image is uploaded by sending a POST request
with the upload_id to a configured URL. The webhook is fire-and-forget and does not affect
the upload response.
Set WEBHOOK_URL to enable this feature. Optionally set WEBHOOK_SECRET to enable
HMAC-SHA256 request signing. When set, every request carries:
X-Lenzr-Timestamp— dispatch time as Unix secondsX-Lenzr-Signature—sha256=<hex_digest>over<timestamp>.<raw_body>
Receivers should verify the signature with hmac.compare_digest and reject any
request whose timestamp is older than a small tolerance (e.g. 5 minutes) to
defend against replays.
The easiest way to set up the Lenzr Server is by using docker-compose.
Start the server as a daemon service with
docker compose up -dIt is reachable on port 8000 afterwards.
To stop the server, do
docker compose downAlternatively, you can manually run the server without Docker by executing
uv run fastapi run src/lenzr_server/main.pyThis will install all necessary dependencies and start the server locally.
This shall be a guide for contributing to the Lenzr Server project.
At first, install all development dependencies with
uv sync --devTo automatically run checks when you create a commit, install the hooks:
uv run pre-commit installYou can also run the checks manually with
uv run pre-commit run --all-filesTo automatically reload the server on code changes, you can use the following command:
uv run fastapi run --reload src/lenzr_server/main.pyYou can also use the compose.dev.yaml file for a reloading setup. For that, run
docker compose -f compose.yaml -f compose.dev.yaml up --buildOn a change of the database model, one needs to create a new alembic migration to
update already existing databases to the newest state. The simplest solution
is to use the proper compose profile create_alembic_migration for that:
docker compose -f compose.yaml -f compose.dev.yaml --profile create_alembic_migration up --buildTo run the tests, you can use the following command:
uv run pytestThis shall include a list of commands to effectively develop on the project.
To add a new dependency, you can use the following command:
uv add <package_name>This will also update the uv.lock file with the necessary changes.
If the package is only needed for development purposes (like testing or linting), you can add it to the dev group:
uv add --dev <package_name>To upgrade the versions of the dependencies in the uv.lock file, you can use the following command:
uv lock --upgrade