""" Election Process Assistant Application Helps users understand the election process, timelines, and steps interactively. """ from flask import Flask, request from flask_sqlalchemy import SQLAlchemy from flask_cors import CORS from flask_socketio import SocketIO, emit import os import logging db = SQLAlchemy() socketio = SocketIO(cors_allowed_origins="*") # Configure logging logging.basicConfig( level=logging.INFO, format='%(asctime)s [%(levelname)s] %(name)s: %(message)s', ) logger = logging.getLogger(__name__) def create_app(config_name: str = 'development') -> Flask: """ Application factory for creating Flask app instances. Args: config_name: One of 'development', 'testing', 'production' Returns: Configured Flask application """ basedir = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) app = Flask( __name__, template_folder=os.path.join(basedir, 'templates'), static_folder=os.path.join(basedir, 'static'), ) # ── Configuration ──────────────────────────────────── from app.config import CONFIG_MAP app.config.from_object(CONFIG_MAP.get(config_name, CONFIG_MAP['development'])) # ── Extensions ─────────────────────────────────────── db.init_app(app) CORS(app, resources={r"/api/*": {"origins": "*"}}) socketio.init_app(app) # ── Security headers ───────────────────────────────── from app.security import apply_security_headers app.after_request(apply_security_headers) # ── Blueprints ─────────────────────────────────────── from app.routes import main_bp, api_bp app.register_blueprint(main_bp) app.register_blueprint(api_bp, url_prefix='/api') # ── WebSocket handlers ─────────────────────────────── @socketio.on('connect') def handle_connect(data=None): from app.realtime import handle_client_connected handle_client_connected(request.sid, data) logger.info('WebSocket client connected: %s', request.sid) @socketio.on('disconnect') def handle_disconnect(): from app.realtime import handle_client_disconnected handle_client_disconnected(request.sid) logger.info('WebSocket client disconnected: %s', request.sid) @socketio.on('request_timeline') def handle_timeline_request(): from app.realtime import stream_timeline_events emit('timeline_data', {'events': stream_timeline_events()}) @socketio.on('request_stats') def handle_stats_request(): from app.realtime import get_live_stats emit('live_stats', get_live_stats()) # ── DB bootstrap ───────────────────────────────────── with app.app_context(): db.create_all() from app.models import seed_election_data seed_election_data() logger.info('Database initialized and seeded for %s', config_name) return app