A lightweight, terminal-driven attendance system with secure public session access via Cloudflare Tunnel and QR-based student entry.
- Minimal dependencies
- SQLite-based session storage with WAL mode
- Terminal-first workflow
- QR-driven attendance capture
- Docker-compatible deployment
- Ctrl+C protection — prompts confirmation before exit
- Per-IP rate limiting to prevent spam
- Built-in duplicate submission protection
- Atomic submission count — race-condition safe under concurrent load
- Export attendance as CSV and JSON on exit via
--export - Handles 200 concurrent requests with 99.5% success rate
- Maintains low average latency (~0.26–0.34s under load)
- Built-in duplicate submission protection (149/150 blocked in testing)
| Layer | Technology |
|---|---|
| Language | Python 3.10+ |
| Web Framework | FastAPI |
| ASGI Server | Uvicorn |
| Database | SQLite (WAL mode) |
| Input Validation | Pydantic |
| Rate Limiting | SlowAPI |
| Tunneling | Cloudflare Tunnel |
| QR Generation | qrencode (CLI) |
| Containerization | Docker |
- python3
- python3-venv
- sqlite3
- cloudflared
- qrencode
- Docker (optional)
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txtpython3 main.py --course <course-name> --batch <batch-name> --total <number-of-students> --db <path-to-db-file>Example:
python3 main.py --course cs50 --batch fall-101 --total 120 --db db/ug-cs.dbAdd --export to automatically save attendance as CSV and JSON to backup/ when the server exits. Example:
python3 main.py --course cs50 --batch fall-101 --total 120 --db db/ug-cs.db --exportdocker build -t presenz-image:latest .docker run -it --rm -p 8080:8080 -v $(pwd)/db:/app/db presenz-image:latest --course <course-name> --batch <batch-name> --total <number-of-students> --db <path-to-db-file>Example:
docker run -it --rm -p 8080:8080 -v $(pwd)/db:/app/db presenz-image:latest --course cs50 --batch fall-101 --total 120 --db db/ug-cs.dbExpose backend running on localhost:8080:
cloudflared tunnel --url http://localhost:8080This will generate a public URL.
qrencode -t ANSIUTF8 "<public-url>"Students scan this QR to access the session.
All settings are managed via config/config.json:
| Key | Description | Default |
|---|---|---|
server.host |
Server bind address | 0.0.0.0 |
server.port |
Server port | 8080 |
database.wal_mode |
Enable SQLite WAL mode | true |
database.timeout_seconds |
SQLite connection timeout | 5 |
session.session_code_length |
Length of session code | 8 |
security.rate_limit |
Per-IP rate limit | 5/minute |
killswitch.inactivity_timeout_minutes |
Auto-shutdown after inactivity | 3 |
export.backup_path |
Export output directory | ./backup/ |
| Action | Method |
|---|---|
| Graceful exit | Type terminate in terminal |
| Confirmed exit | Press Ctrl+C → type y |
| Auto-shutdown | No activity for inactivity_timeout_minutes |
This project is licensed under Apache License 2.0. Free to use, modify, and learn from.
If you like this project, consider giving it a ⭐ on GitHub!