""" Public Web Frontend - Flask Application Factory This is a lightweight web frontend that provides HTML/HTMX UI for the Code of Conquest game. All business logic is handled by the API backend - this frontend only renders views and makes HTTP requests to the API. """ from flask import Flask from flask import render_template import structlog import yaml import os from pathlib import Path logger = structlog.get_logger(__name__) def load_config(): """Load configuration from YAML file based on environment.""" env = os.getenv("FLASK_ENV", "development") config_path = Path(__file__).parent.parent / "config" / f"{env}.yaml" with open(config_path, 'r') as f: config = yaml.safe_load(f) logger.info("configuration_loaded", env=env, config_path=str(config_path)) return config def create_app(): """Create and configure the Flask application.""" app = Flask(__name__, template_folder="../templates", static_folder="../static") # Load configuration config = load_config() app.config.update(config) # Configure secret key from environment app.config['SECRET_KEY'] = os.getenv('SECRET_KEY', 'dev-secret-key-change-in-production') # Context processor to make API config and user available in templates @app.context_processor def inject_template_globals(): """Make API base URL and current user available to all templates.""" from .utils.auth import get_current_user return { 'api_base_url': app.config.get('api', {}).get('base_url', 'http://localhost:5000'), 'current_user': get_current_user() } # Register blueprints from .views.auth_views import auth_bp from .views.character_views import character_bp from .views.game_views import game_bp app.register_blueprint(auth_bp) app.register_blueprint(character_bp) app.register_blueprint(game_bp) # Register dev blueprint only in development env = os.getenv("FLASK_ENV", "development") if env == "development": from .views.dev import dev_bp app.register_blueprint(dev_bp) logger.info("dev_blueprint_registered", message="Dev testing routes available at /dev") # Error handlers @app.errorhandler(404) def not_found(error): return render_template('errors/404.html'), 404 @app.errorhandler(500) def internal_error(error): logger.error("internal_server_error", error=str(error)) return render_template('errors/500.html'), 500 logger.info("flask_app_created", blueprints=["auth", "character", "game"]) return app