Files
digiserver-v2/docs/04-application-core.md
T

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_old is 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 — exposes server_version, build_date, logo_exists to all templates.
  • inject_user_theme — exposes the authenticated user's theme (light/dark) for the UI toggle.

9. Template Filters

  • localtime — converts naive/UTC datetimes to local time with a configurable strftime format (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