5.9 KiB
04 · Application Core
Covers the application factory, configuration, extensions, middleware, CLI commands, context processors, and template layer. This is Community 4 in the Graphify knowledge graph.
1. Application Factory — app/app.py
The entire app is constructed by create_app(config_name=None):
flowchart TD
A["create_app()"] --> B["Set instance_path"]
B --> C["Load config: Dev / Prod / Test"]
C --> D["ProxyFix middleware"]
D --> E["ScriptNameFix middleware"]
E --> F["init extensions: db bcrypt login migrate cache cors"]
F --> G["configure_login_manager()"]
G --> H["register_blueprints()"]
H --> I["register_error_handlers()"]
I --> J["register_commands()"]
J --> K["register_context_processors()"]
K --> L["register_template_filters()"]
L --> M["init_portal_sso(app)"]
M --> N["db.create_all() (idempotent)"]
N --> O["return app"]
Blueprint registration
def register_blueprints(app):
from app.blueprints.main import main_bp
from app.blueprints.auth import auth_bp
from app.blueprints.admin import admin_bp
from app.blueprints.players import players_bp
from app.blueprints.content import content_bp
from app.blueprints.playlist import playlist_bp
from app.blueprints.api import api_bp
...
Note:
app.blueprints.content_oldis not imported — it is dead/legacy code.
2. Configuration — app/config.py
Four classes: Config (base) → DevelopmentConfig, ProductionConfig, TestingConfig.
| Setting | Value | Notes |
|---|---|---|
MAX_CONTENT_LENGTH |
2 GB | upload cap |
UPLOAD_FOLDER |
app/static/uploads |
media |
UPLOAD_FOLDERLOGO |
app/static/resurse |
logos |
ALLOWED_EXTENSIONS |
png jpg jpeg gif bmp mp4 avi mkv mov webm pdf ppt pptx | |
PERMANENT_SESSION_LIFETIME |
30 min | |
SESSION_COOKIE_SECURE |
False (True in prod) | |
ITEMS_PER_PAGE |
20 | |
SERVER_VERSION |
2.0.0 | shown in UI footer |
PLAYER_CODE_DIR |
/app/data/player |
staged player source |
PLAYER_REPO_URL |
env PLAYER_REPO_URL |
Kiwy-Signage repo |
| DB (dev) | instance/dev.db |
|
| DB (prod) | instance/dashboard.db |
|
| DB (test) | in-memory |
3. Extensions — app/extensions.py
Centralizes shared singletons:
db = SQLAlchemy()
bcrypt = Bcrypt()
login_manager = LoginManager() # login_view='auth.login'
migrate = Migrate()
cache = Cache()
cors = CORS()
CORS is configured in create_app for /api/*: all origins, GET/POST/OPTIONS/PUT/DELETE, supports credentials.
4. Middleware
ProxyFix (Werkzeug)
app.wsgi_app = ProxyFix(app.wsgi_app, x_for=1, x_proto=1, x_host=1, x_port=1) — trusts one reverse-proxy hop (Caddy / umbrella nginx).
ScriptNameFix — app/utils/script_name_fix.py
ScriptNameFix WSGI middleware sets SCRIPT_NAME from HTTP_X_SCRIPT_NAME so url_for() generates correct paths when the app is mounted under a sub-path (e.g. /digiserver).
5. Login Manager
login_manager.login_view = 'auth.login'
login_manager.login_message = 'Please log in to access this page.'
@login_manager.user_loader
def load_user(user_id):
return User.query.get(int(user_id))
6. Error Handlers
| Code | Template | Behaviour |
|---|---|---|
| 404 | errors/404.html |
Not found |
| 403 | errors/403.html |
Forbidden |
| 500 | errors/500.html |
Rolls back DB session |
| 413 | errors/413.html |
Payload too large |
| 408 | errors/408.html |
Request timeout |
The /api blueprint registers its own JSON 404/405/500 handlers.
7. CLI Commands
| Command | Purpose |
|---|---|
flask init-db |
db.create_all() |
flask create-admin --username X |
Create admin user (prompts for password) |
flask seed-db |
Seed sample data (blocked in production) |
8. Context Processors
inject_config— exposesserver_version,build_date,logo_existsto all templates.inject_user_theme— exposes the authenticated user'stheme(light/dark) for the UI toggle.
9. Template Filters
localtime— converts naive/UTC datetimes to local time with a configurablestrftimeformat (default%Y-%m-%d %H:%M).
10. Template & Static Layout
app/templates/
├── base.html ← main layout (theme, logos, nav)
├── dashboard.html
├── auth/ login.html, register.html, change_password.html
├── admin/ admin.html, user_management.html, leftover_media.html,
│ dependencies.html, customize_logos.html, editing_users.html,
│ https_config.html, build_player.html
├── content/ content_list.html (legacy), content_list_new.html (modern),
│ media_library.html, upload_content.html (legacy),
│ upload_media.html, manage_playlist_content.html, edit_content.html
├── players/ players_list.html, add_player.html, edit_player.html,
│ manage_player.html, player_page.html, player_fullscreen.html,
│ edited_media.html, edited_media_report.html, _deploy_badge.html
└── errors/ 403.html, 404.html, 500.html (+413/408)
app/static/
├── icons/ edit, home, info, monitor, moon, playlist, sun, trash, upload, warning (SVG)
├── uploads/ uploaded media + edited_media/<content_id>/ (versioned edits)
└── (resurse/ logo storage — referenced by config)
11. Portal SSO — app/utils/portal_sso.py
init_portal_sso(app) registers a before_request hook that reads X-Auth-Username / X-Auth-Role headers (set by the umbrella nginx gateway). If present, it auto-creates and logs in the local User (_get_or_create_user). This lets the app sit behind an existing corporate SSO portal.
Next: 05 · Blueprints & API