import os from dotenv import load_dotenv from flask import Flask from applications.common.script import init_script from applications.config import BaseConfig, get_config_by_name from applications.extensions import init_plugs from applications.view import init_bps # 项目根目录 = 本文件父目录的父目录 BASE_DIR = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) def create_app(): # 1) 先加载 .env(在 BaseConfig 读取 os.environ 之前) # override=False:环境变量优先级高于 .env,便于 CI/CD 在部署时再覆盖 load_dotenv(os.path.join(BASE_DIR, ".env"), override=False) app = Flask(BASE_DIR) # 2) 根据 PEAR_ENV / FLASK_ENV 选择配置类,默认 dev env_name = os.environ.get("PEAR_ENV") or os.environ.get("FLASK_ENV") or "dev" config_cls = get_config_by_name(env_name) app.config.from_object(config_cls) # 3) 把 BaseConfig 默认值里没写、但 .env 可能写了的 SQLALCHEMY_DATABASE_URI 等再覆盖一次 if os.environ.get("SQLALCHEMY_DATABASE_URI"): app.config["SQLALCHEMY_DATABASE_URI"] = os.environ["SQLALCHEMY_DATABASE_URI"] # 3.5) 让配置类有机会做运行时校验(例如 ProConfig 强制要求 SECRET_KEY) if hasattr(config_cls, "init_app"): config_cls.init_app(app) # 4) 注册 flask 组件 / 蓝图 / 命令 init_plugs(app) init_bps(app) init_script(app) return app