2026-08-03 10:02:12 +02:00
|
|
|
import os
|
2026-07-22 16:37:53 +02:00
|
|
|
import time
|
2026-08-03 10:02:12 +02:00
|
|
|
from flask import Flask
|
2026-07-22 16:37:53 +02:00
|
|
|
from flask_sqlalchemy import SQLAlchemy
|
2026-08-03 10:02:12 +02:00
|
|
|
from flask_wtf import CSRFProtect
|
2026-07-22 16:37:53 +02:00
|
|
|
from sqlalchemy.exc import OperationalError
|
2026-08-03 10:02:12 +02:00
|
|
|
from dotenv import load_dotenv
|
|
|
|
|
|
|
|
|
|
load_dotenv()
|
2026-07-22 16:37:53 +02:00
|
|
|
|
|
|
|
|
db = SQLAlchemy()
|
2026-08-03 10:02:12 +02:00
|
|
|
csrf = CSRFProtect()
|
|
|
|
|
|
2026-07-22 16:37:53 +02:00
|
|
|
|
|
|
|
|
def create_app():
|
|
|
|
|
app = Flask(__name__)
|
2026-08-03 10:02:12 +02:00
|
|
|
|
|
|
|
|
# --- Configuration depuis l'environnement ---
|
|
|
|
|
app.config["SECRET_KEY"] = os.environ.get(
|
|
|
|
|
"SECRET_KEY", "change-me-in-production"
|
|
|
|
|
)
|
|
|
|
|
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
|
|
|
|
|
|
|
|
|
|
db_user = os.environ.get("MYSQL_USER", "jfgiraud")
|
|
|
|
|
db_pass = os.environ.get("MYSQL_PASSWORD", "")
|
|
|
|
|
db_host = os.environ.get("MYSQL_HOST", "db")
|
|
|
|
|
db_port = os.environ.get("MYSQL_PORT", "3306")
|
|
|
|
|
db_name = os.environ.get("MYSQL_DATABASE", "bolsa")
|
|
|
|
|
# DATABASE_URL prend la priorité si défini
|
|
|
|
|
app.config["SQLALCHEMY_DATABASE_URI"] = os.environ.get(
|
|
|
|
|
"DATABASE_URL",
|
|
|
|
|
f"mysql+pymysql://{db_user}:{db_pass}@{db_host}:{db_port}/{db_name}",
|
|
|
|
|
)
|
2026-07-22 16:37:53 +02:00
|
|
|
|
|
|
|
|
db.init_app(app)
|
2026-08-03 10:02:12 +02:00
|
|
|
csrf.init_app(app)
|
|
|
|
|
|
|
|
|
|
# Enregistrement des modèles ORM (nécessaire avant db.create_all)
|
|
|
|
|
from app import models # noqa: F401
|
2026-07-22 16:37:53 +02:00
|
|
|
|
2026-08-03 10:02:12 +02:00
|
|
|
# Tentative de connexion au démarrage du conteneur (MySQL peut mettre du temps à être prêt)
|
2026-07-22 16:37:53 +02:00
|
|
|
with app.app_context():
|
|
|
|
|
max_retries = 15
|
|
|
|
|
delay = 2
|
|
|
|
|
for i in range(max_retries):
|
|
|
|
|
try:
|
|
|
|
|
db.create_all()
|
|
|
|
|
print("Base de données connectée et tables initialisées avec succès.")
|
|
|
|
|
break
|
2026-08-03 10:02:12 +02:00
|
|
|
except OperationalError:
|
|
|
|
|
print(f"Tentative {i+1}/{max_retries} : MySQL n'est pas encore prêt. "
|
|
|
|
|
f"Nouvelle tentative dans {delay}s...")
|
2026-07-22 16:37:53 +02:00
|
|
|
time.sleep(delay)
|
|
|
|
|
else:
|
|
|
|
|
raise Exception("Impossible d'initialiser la base de données après plusieurs tentatives.")
|
|
|
|
|
|
2026-08-09 09:50:49 +02:00
|
|
|
# Enregistrement des routes (Blueprints)
|
|
|
|
|
from app.routes import (
|
|
|
|
|
actions_bp,
|
|
|
|
|
analyse_bp,
|
|
|
|
|
auth_bp,
|
|
|
|
|
comptes_bp,
|
|
|
|
|
historique_bp,
|
|
|
|
|
menu_bp,
|
|
|
|
|
ordres_bp,
|
|
|
|
|
societes_bp,
|
|
|
|
|
utilisateurs_bp,
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
app.register_blueprint(auth_bp)
|
|
|
|
|
app.register_blueprint(menu_bp)
|
|
|
|
|
app.register_blueprint(utilisateurs_bp)
|
|
|
|
|
app.register_blueprint(actions_bp)
|
|
|
|
|
app.register_blueprint(societes_bp)
|
|
|
|
|
app.register_blueprint(historique_bp)
|
|
|
|
|
app.register_blueprint(analyse_bp)
|
|
|
|
|
app.register_blueprint(ordres_bp)
|
|
|
|
|
app.register_blueprint(comptes_bp)
|
2026-07-22 16:37:53 +02:00
|
|
|
|
|
|
|
|
return app
|
|
|
|
|
|
2026-08-03 10:02:12 +02:00
|
|
|
|
2026-07-22 16:37:53 +02:00
|
|
|
# Expose 'app' pour que run.py puisse l'importer directement
|
2026-08-03 10:02:12 +02:00
|
|
|
app = create_app()
|