Skip to content

Project Architecture

Directory Structure

app/
├── __init__.py          # App factory (create_app), extension init, DB bootstrap
├── models.py            # SQLAlchemy models: user, SSID
├── pages.py             # Static page blueprint
├── cron.py              # Standalone cron script for scheduled password rotation
├── ssid.py              # Per-SSID cron entry point
├── logging_config.py    # Centralised logging configuration
├── wsgi.py              # WSGI entry point
├── api/
│   ├── unifi.py         # UniFi controller API client
│   └── omada.py         # TP-Link Omada controller API client
├── config/
│   ├── config.py        # JSON config read/write helpers
│   ├── crontab.py       # Cron job CRUD via python-crontab
│   └── file/
│       └── config.json  # Runtime config (controller IP, API credentials, Wi-Fi info)
├── routes/
│   ├── admin.py         # Admin dashboard, user management, SSID rescan
│   ├── auth.py          # Login / logout
│   ├── setup.py         # First-run initialisation wizard
│   └── ssid.py          # Password change, QR code, cron scheduling
├── utilities/
│   ├── genPW.py         # Cryptographically secure password generator
│   └── genQR.py         # Wi-Fi QR code image generator
├── static/              # CSS, JS, images (Bootstrap + custom)
└── templates/           # Jinja2 HTML templates

Request Lifecycle

Browser → Gunicorn → Flask app (create_app)
                    Blueprint routing
                    ├── /login         → auth.bp
                    ├── /admin         → admin.bp
                    ├── /changepw/:id  → ssid.bp
                    ├── /initApp       → setup.bp
                    └── /             → pages.bp
                    SQLite (KeyShift.db via SQLAlchemy)
                    JSON config (app/config/file/config.json)
                    Controller API (UniFi / Omada)

Extension Stack

Extension Purpose
Flask-SQLAlchemy ORM & SQLite database
Flask-Migrate Database schema migrations (Alembic)
Flask-Login Session-based authentication
Flask-Limiter Rate limiting (200/day, 20/hour default)
Flask-WTF CSRF protection
Flask-Bcrypt Password hashing