REST API of OpenSchichtplaner5 — the FastAPI service layer over libopenschichtplaner5 (sp5lib): auth/2FA, employees, schedule, absences, reports, notifications and more.
Project description
openschichtplaner5-api
The REST API behind OpenSchichtplaner5 —
a pip-installable FastAPI service over
libopenschichtplaner5 (sp5lib),
serving shift-planning data from the original Schichtplaner5 FoxPro .DBF files or the
SQLite/PostgreSQL mirror: auth/2FA with JWT sessions, employees, schedule, absences,
reports/exports (incl. the original personnel table via GET /api/personnel-table and
statistics over a free evaluation period), leave-entitlement administration
(POST /api/leave-entitlements/forfeit, annual close), notifications (SSE), webhooks,
iCal feeds and more. All Soll/Ist/demand figures are computed by the sp5lib
calculation facade — the API carries no arithmetic of its own.
Import name: the distribution is
openschichtplaner5-api, but the importable package issp5api(mirroringlibopenschichtplaner5→sp5lib). It was extracted from the main app'sbackend/api/with full git history.
📖 Detailed documentation lives in the project wiki — endpoint overview, auth & permissions, full environment reference, deployment guides. Architecture notes are in docs/architecture.md.
What's inside
| Module | Purpose |
|---|---|
sp5api.main |
The FastAPI application (sp5api.main:app) — middlewares, health/metrics, SPA serving |
sp5api.routers.* |
One router per domain: auth, employees, schedule, absences, reports, notifications, availability, overtime, qualification_matrix, recurring_shifts, ical, webhooks, admin, … |
sp5api.dependencies |
Session store, JWT, rate limiting, logging, DB wiring |
sp5api.schemas / sp5api.types |
Pydantic models / type aliases |
sp5api.cache / sp5api.rate_limit_store |
Response caching, rate-limit event log |
Permissions
Roles (Leser < Planer < Admin) gate read/write access; on top of that the
granular 5USER rights of the original (WDUTIES, WABSENCES, WOVERTIMES,
WNOTES, WDEVIATION, WCYCLEASS, WSWAPONLY, ADDEMPL, WPAST) are
enforced per write route and exposed as a permissions object on
GET /api/auth/me; WPAST=0 blocks every write with a date in the past, bulk
routes included. The built-in Admin account and the last remaining
administrator cannot be demoted or deleted. Full details:
wiki → Auth & Permissions.
Installation
pip install openschichtplaner5-api
Prefer containers? See Docker below — the image runs standalone without a local Python environment.
Running
SP5_DB_PATH=/path/to/SP5/Daten python -m uvicorn sp5api.main:app --host 0.0.0.0 --port 8000
Key environment variables
| Variable | Default | Purpose |
|---|---|---|
SP5_DB_PATH |
(set it!) | Directory with the Schichtplaner5 .DBF files |
SP5_JWT_SECRET / SECRET_KEY |
random per process | JWT signing secret — set it in production |
SP5_BACKEND_DIR |
package parent dir | Resource root (data/, api/data/, uploads), shared contract with sp5lib — set it in installed deployments |
SP5_BACKUP_DIR |
<SP5_DB_PATH>/../backups |
Target directory for (auto-)backups; if it is not writable, the startup auto-backup is skipped with an info log |
DB_BACKEND / DATABASE_URL |
dbf |
Switch to the PostgreSQL mirror (via sp5lib) |
Everything else (SPA serving, CORS, rate limits, brute-force lockout, SMTP,
logging, password policy …) is covered by the
wiki → environment reference
and the main app's .env.example.
Docker
Production-ready multi-stage image (slim runtime, non-root, HEALTHCHECK on
/api/health, EXPOSE 8000; SP5_DB_PATH=/app/data, SP5_BACKEND_DIR=/app/backend):
# local operation: DBF dir + optional .env (SECRET_KEY!), see docker-compose.yml
SP5_DBF_DIR=/path/to/SP5/Daten docker compose up --build
Standalone, without compose — mount the DBF directory to /app/data and pass
the environment via .env (at minimum SECRET_KEY, see
Key environment variables):
docker build -t openschichtplaner5-api .
echo "SECRET_KEY=$(openssl rand -hex 32)" > .env
docker run -d --name sp5-api -p 8000:8000 \
-v /path/to/SP5/Daten:/app/data \
--env-file .env \
openschichtplaner5-api
# health check
curl http://localhost:8000/api/health
# → {"status":"healthy","checks":{"db":"ok",...},"version":"1.2.0",...}
The build installs the library from PyPI by default
(libopenschichtplaner5[postgres]==1.7.0). To build against a different
state, override the build arg:
docker build --build-arg LIB_SOURCE=git+https://github.com/mschabhuettl/libopenschichtplaner5.git@main .
PostgreSQL mode (standalone)
With DB_BACKEND=postgresql and DATABASE_URL set, the API runs against the
PostgreSQL mirror. The initial schema is created automatically by the ORM
(sp5lib) on first connect — no Alembic tree is required. The Alembic
migration tree lives in the main application repo (backend/alembic) and is
intentionally not bundled with this package (a copy would drift), so the
startup auto-migration is skipped with an info log when no alembic.ini is
found. To apply future schema migrations in a standalone deployment, point
SP5_BACKEND_DIR at a directory containing alembic.ini + alembic/ (e.g. a
checkout of the main app's backend/).
Development
python3 -m venv .venv && . .venv/bin/activate
pip install -e ".[dev]"
ruff check .
pytest
To develop against a local clone of the library instead of the PyPI release:
pip install -e "../libopenschichtplaner5[postgres]"
data/ and api/data/ at the repo root are runtime-state seeds (skills, wishes,
notification settings) used by the test suite — the same layout the main app keeps
under backend/, resolved via SP5_BACKEND_DIR. tests/fixtures/ holds the DBF
fixture database.
Releasing
Tag vX.Y.Z and push — the release workflow builds
sdist+wheel and publishes to PyPI via Trusted Publishing (OIDC).
License
MIT — see LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file openschichtplaner5_api-1.3.0.tar.gz.
File metadata
- Download URL: openschichtplaner5_api-1.3.0.tar.gz
- Upload date:
- Size: 407.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
80645c1be460e28f80b5df2073ca4fd699b1af84fb7ca012d347f1ca94ef9270
|
|
| MD5 |
915768875572e5f288709068e9000cbb
|
|
| BLAKE2b-256 |
1e334ccba33a99e9f1af995d4e078639edc101c171dfa6179240be1d22f9acbb
|
Provenance
The following attestation bundles were made for openschichtplaner5_api-1.3.0.tar.gz:
Publisher:
release.yml on mschabhuettl/openschichtplaner5-api
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
openschichtplaner5_api-1.3.0.tar.gz -
Subject digest:
80645c1be460e28f80b5df2073ca4fd699b1af84fb7ca012d347f1ca94ef9270 - Sigstore transparency entry: 1803924798
- Sigstore integration time:
-
Permalink:
mschabhuettl/openschichtplaner5-api@0b55d7cdad55b94df213af72d6e76e069cfe71fb -
Branch / Tag:
refs/tags/v1.3.0 - Owner: https://github.com/mschabhuettl
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@0b55d7cdad55b94df213af72d6e76e069cfe71fb -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file openschichtplaner5_api-1.3.0-py3-none-any.whl.
File metadata
- Download URL: openschichtplaner5_api-1.3.0-py3-none-any.whl
- Upload date:
- Size: 190.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
33e9dcba4eea95114d589a9b4e783e8aeeaddb3bd2bb24bc03f63eae53b0b05f
|
|
| MD5 |
0d1fffac95bc97ff17768f715a72358c
|
|
| BLAKE2b-256 |
e5292ce338b25e1f51dfb460d95f22a401af90d696698b8c554fbe25359d2f85
|
Provenance
The following attestation bundles were made for openschichtplaner5_api-1.3.0-py3-none-any.whl:
Publisher:
release.yml on mschabhuettl/openschichtplaner5-api
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
openschichtplaner5_api-1.3.0-py3-none-any.whl -
Subject digest:
33e9dcba4eea95114d589a9b4e783e8aeeaddb3bd2bb24bc03f63eae53b0b05f - Sigstore transparency entry: 1803924879
- Sigstore integration time:
-
Permalink:
mschabhuettl/openschichtplaner5-api@0b55d7cdad55b94df213af72d6e76e069cfe71fb -
Branch / Tag:
refs/tags/v1.3.0 - Owner: https://github.com/mschabhuettl
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@0b55d7cdad55b94df213af72d6e76e069cfe71fb -
Trigger Event:
workflow_dispatch
-
Statement type: