from flask import Flask from flask_sqlalchemy import SQLAlchemy from flask_login import LoginManager from dotenv import load_dotenv from pathlib import Path import os db = SQLAlchemy() login_manager = LoginManager() def create_app(): # --- Chemins --- base_dir = Path(__file__).resolve().parent template_dir = base_dir.parent / 'frontend' / 'templates' static_dir = base_dir.parent / 'frontend' / 'static' instance_path = base_dir.parent / 'instance' instance_path.mkdir(parents=True, exist_ok=True) # --- Chargement des variables d'environnement --- env_path = base_dir.parent / '.env' load_dotenv(env_path) # --- Vérification de la clé secrète --- secret = os.getenv('FLASK_SECRET') if not secret: raise RuntimeError("FLASK_SECRET must be set in environment") # --- Création de l'application --- app = Flask( __name__, template_folder=str(template_dir), static_folder=str(static_dir), instance_path=str(instance_path) ) # --- Configuration --- app.config.update( SECRET_KEY=secret, SQLALCHEMY_DATABASE_URI=f"sqlite:///{instance_path / 'users.db'}", SQLALCHEMY_TRACK_MODIFICATIONS=False, SESSION_COOKIE_HTTPONLY=True, SESSION_COOKIE_SAMESITE='Lax', SESSION_COOKIE_SECURE=os.getenv("FLASK_ENV") == "production" ) # --- Initialisation des extensions --- db.init_app(app) login_manager.init_app(app) login_manager.login_view = "login" login_manager.session_protection = "strong" login_manager.login_message = "Veuillez vous connecter pour accéder à cette page." login_manager.login_message_category = "warning" from backend import routes from backend.models import User # Loader pour Flask-Login @login_manager.user_loader def load_user(user_id): return User.query.get(int(user_id)) # --- Chargement différé des modèles et routes --- with app.app_context(): # Création de la DB si nécessaire db.create_all() # Initialisation des routes routes.init_app(app) return app