""" Flask Application Factory Creates and configures the Flask application with SocketIO support for real-time updates of the Markov economics simulation. """ import os from flask import Flask from flask_socketio import SocketIO from config import config from app.models import SimulationManager # Initialize SocketIO with enhanced proxy support # For Gunicorn compatibility, we need to set the async_mode to 'gevent' socketio = SocketIO( cors_allowed_origins="*", async_mode='gevent' if os.getenv('FLASK_ENV') == 'production' else 'threading', logger=False, # Disable to avoid log spam in production engineio_logger=False, # Transport order: try websocket first, then polling transports=['websocket', 'polling'], # Ping settings for better connection detection ping_timeout=60, ping_interval=25, # Proxy compatibility settings allow_upgrades=True, upgrade_timeout=30 ) # Global simulation manager instance simulation_manager = SimulationManager() def create_app(config_name=None): """ Create and configure the Flask application. Args: config_name: Configuration profile to use Returns: Configured Flask application instance """ if config_name is None: config_name = os.getenv('FLASK_CONFIG', os.getenv('FLASK_ENV', 'development')) app = Flask(__name__) app.config.from_object(config[config_name]) # Configure for reverse proxy from werkzeug.middleware.proxy_fix import ProxyFix app.wsgi_app = ProxyFix(app.wsgi_app, x_for=1, x_proto=1, x_host=1, x_prefix=1) # Initialize extensions with proxy-friendly settings socketio.init_app( app, async_mode='gevent' if config_name == 'production' else 'threading', cors_allowed_origins="*", allow_upgrades=True, transports=['websocket', 'polling'], ping_timeout=60, ping_interval=25, upgrade_timeout=30, manage_session=False # Important for proxy compatibility ) # Register blueprints from .routes.main import main_bp from .routes.api import api_bp app.register_blueprint(main_bp) app.register_blueprint(api_bp, url_prefix='/api') return app