Metadata-Version: 2.4
Name: openschichtplaner5-api
Version: 1.1.1
Summary: REST API of OpenSchichtplaner5 — the FastAPI service layer over libopenschichtplaner5 (sp5lib): auth/2FA, employees, schedule, absences, reports, notifications and more.
Author-email: Matthias Schabhüttl <matthias@matthiasschabhuettl.com>
License-Expression: MIT
Project-URL: Homepage, https://github.com/mschabhuettl/openschichtplaner5-api
Project-URL: Source, https://github.com/mschabhuettl/openschichtplaner5-api
Project-URL: Changelog, https://github.com/mschabhuettl/openschichtplaner5-api/blob/main/CHANGELOG.md
Project-URL: Issues, https://github.com/mschabhuettl/openschichtplaner5-api/issues
Project-URL: Main application, https://github.com/mschabhuettl/openschichtplaner5
Project-URL: Core library, https://github.com/mschabhuettl/libopenschichtplaner5
Keywords: schichtplaner5,shift-planning,fastapi,rest-api,scheduling
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Framework :: FastAPI
Classifier: Topic :: Office/Business :: Scheduling
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: fastapi!=0.136.3,>=0.104.0
Requires-Dist: uvicorn[standard]>=0.24.0
Requires-Dist: pydantic>=2.0.0
Requires-Dist: starlette>=0.27.0
Requires-Dist: anyio>=3.7.0
Requires-Dist: httpx>=0.24.0
Requires-Dist: python-multipart>=0.0.7
Requires-Dist: python-dotenv>=1.0.0
Requires-Dist: slowapi>=0.1.9
Requires-Dist: fpdf2>=2.7.0
Requires-Dist: bcrypt>=4.0.0
Requires-Dist: PyJWT>=2.8.0
Requires-Dist: pyotp>=2.9.0
Requires-Dist: qrcode[pil]>=7.4
Requires-Dist: openpyxl>=3.1.0
Requires-Dist: psutil>=5.9.0
Requires-Dist: Pillow>=10.0.0
Requires-Dist: SQLAlchemy>=2.0.0
Requires-Dist: libopenschichtplaner5[postgres]>=1.6.0
Provides-Extra: dev
Requires-Dist: pytest>=7.4.0; extra == "dev"
Requires-Dist: pytest-cov>=4.1.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.23.0; extra == "dev"
Requires-Dist: ruff>=0.1.0; extra == "dev"
Dynamic: license-file

# openschichtplaner5-api

[![CI](https://github.com/mschabhuettl/openschichtplaner5-api/actions/workflows/ci.yml/badge.svg)](https://github.com/mschabhuettl/openschichtplaner5-api/actions/workflows/ci.yml)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)

The REST API behind [**OpenSchichtplaner5**](https://github.com/mschabhuettl/openschichtplaner5) —
a pip-installable FastAPI service over
[**libopenschichtplaner5**](https://github.com/mschabhuettl/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, notifications (SSE), webhooks, iCal feeds and more.

> **Import name:** the distribution is `openschichtplaner5-api`, but the importable
> package is **`sp5api`** (mirroring `libopenschichtplaner5` → `sp5lib`).
> It was extracted from the main app's `backend/api/` with full git history.

## 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 |

## Installation

```bash
pip install openschichtplaner5-api
```

## Running

```bash
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_BACKEND_DIR` | package parent dir | Host-app resource root: `<dir>/data`, `<dir>/api/data`, `<dir>/api/uploads`, alembic config. Shared contract with `sp5lib` — set it in installed deployments |
| `SP5_FRONTEND_DIST` | `<SP5_BACKEND_DIR>/../frontend/dist` | Built SPA to serve at `/` (skipped if absent → API-only mode) |
| `SP5_JWT_SECRET` / `SECRET_KEY` | random per process | JWT signing secret |
| `SP5_DEV_MODE` | off | Dev bypass token — never in production |
| `ALLOWED_ORIGINS` | localhost:5173/8000 | CORS origins (comma-separated) |
| `DB_BACKEND` / `DATABASE_URL` | `dbf` | Switch to the PostgreSQL mirror (via `sp5lib`) |

The full list (rate limits, brute-force lockout, SMTP, logging, password policy …) is
documented in the main app's [`.env.example`](https://github.com/mschabhuettl/openschichtplaner5/blob/main/.env.example).

## Development

```bash
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:

```bash
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](.github/workflows/release.yml) builds
sdist+wheel and publishes to PyPI via Trusted Publishing (OIDC).

## License

MIT — see [LICENSE](LICENSE).
