Spaces:
Running
Running
| import os | |
| from flask import Flask | |
| from flask_sqlalchemy import SQLAlchemy | |
| from flask_cors import CORS | |
| db = SQLAlchemy() | |
| # Paths resolved relative to this file's location | |
| _HERE = os.path.dirname(__file__) | |
| _FRONT = os.path.join(_HERE, "..", "frontend") | |
| _DIST = os.path.join(_FRONT, "dist") # React production build | |
| _TEMPLATES = os.path.join(_FRONT, "templates") # Vanilla HTML fallback | |
| def create_app(config_override: dict | None = None) -> Flask: | |
| # Prefer React build if it exists | |
| if os.path.isdir(_DIST): | |
| template_folder = _DIST | |
| static_folder = os.path.join(_DIST, "assets") | |
| static_url_path = "/assets" | |
| else: | |
| template_folder = _TEMPLATES | |
| static_folder = os.path.join(_FRONT, "static") | |
| static_url_path = "/static" | |
| app = Flask( | |
| __name__, | |
| template_folder=template_folder, | |
| static_folder=static_folder, | |
| static_url_path=static_url_path, | |
| ) | |
| # ββ Configuration ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| app.config["SECRET_KEY"] = os.environ.get("SECRET_KEY", "change-me-in-production") | |
| app.config["SQLALCHEMY_DATABASE_URI"] = os.environ.get( | |
| "DATABASE_URL", "sqlite:///breathe.db" | |
| ) | |
| app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False | |
| app.config["SESSION_COOKIE_HTTPONLY"] = True | |
| app.config["SESSION_COOKIE_SAMESITE"] = "None" | |
| app.config["SESSION_COOKIE_SECURE"] = True | |
| if config_override: | |
| app.config.update(config_override) | |
| # ββ Extensions βββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| db.init_app(app) | |
| default_origins = "http://localhost:5173,http://127.0.0.1:5173,https://huggingface.co,https://hf.space" | |
| origins = os.environ.get("CORS_ORIGINS", default_origins).split(",") | |
| CORS(app, supports_credentials=True, origins=origins) | |
| # ββ Blueprints βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| from .routes.auth import auth_bp | |
| from .routes.assessments import assess_bp | |
| from .routes.profile import profile_bp | |
| from .routes.gratitude import gratitude_bp | |
| app.register_blueprint(auth_bp) | |
| app.register_blueprint(assess_bp) | |
| app.register_blueprint(profile_bp) | |
| app.register_blueprint(gratitude_bp) | |
| # ββ Serve SPA ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| from flask import send_from_directory | |
| _dist_or_tmpl = _DIST if os.path.isdir(_DIST) else _TEMPLATES | |
| def index(): | |
| return send_from_directory(_dist_or_tmpl, "index.html") | |
| def catch_all(path): | |
| # Serve any real file that lives inside the dist/template dir | |
| target = os.path.join(_dist_or_tmpl, path) | |
| if os.path.isfile(target): | |
| return send_from_directory(_dist_or_tmpl, path) | |
| # SPA fallback | |
| return send_from_directory(_dist_or_tmpl, "index.html") | |
| # ββ Create tables ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| with app.app_context(): | |
| db.create_all() | |
| # ββ ML model loading βββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| from .ml.ml_engine import init_models | |
| init_models( | |
| psycho_model_dir=os.environ.get("PSYCHO_MODEL_DIR", "models/psychometric"), | |
| roberta_ckpt =os.environ.get("ROBERTA_CKPT", "models/text/roberta-model.pt"), | |
| ) | |
| # ββ Background scheduler βββββββββββββββββββββββββββββββββββββββββββββββββ | |
| from .utils.scheduler import init_scheduler | |
| init_scheduler(app, db) | |
| return app | |