PromptWarElection / app /__init__.py
Mr-TD's picture
feat: initialize 2026 Election Assistant web application with real-time tracking and comprehensive event documentation
3c4d71f
"""
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