2026-03-07 09:01:00 +08:00
|
|
|
"""
|
|
|
|
|
Flask application factory for chat platform backend.
|
|
|
|
|
"""
|
|
|
|
|
import os
|
|
|
|
|
from flask import Flask
|
|
|
|
|
from flask_sqlalchemy import SQLAlchemy
|
|
|
|
|
from flask_migrate import Migrate
|
|
|
|
|
from flask_jwt_extended import JWTManager
|
|
|
|
|
from flask_cors import CORS
|
|
|
|
|
from flask_socketio import SocketIO
|
|
|
|
|
from flask_limiter import Limiter
|
|
|
|
|
from flask_limiter.util import get_remote_address
|
|
|
|
|
from redis import Redis
|
|
|
|
|
|
|
|
|
|
from app.config import config_by_name
|
|
|
|
|
|
|
|
|
|
db = SQLAlchemy()
|
|
|
|
|
migrate = Migrate()
|
|
|
|
|
jwt = JWTManager()
|
|
|
|
|
socketio = SocketIO(cors_allowed_origins="*", async_mode="eventlet")
|
|
|
|
|
limiter = Limiter(key_func=get_remote_address, default_limits=["200 per day", "50 per hour"])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def create_app(config_name=None):
|
|
|
|
|
config_name = config_name or os.getenv("FLASK_ENV", "development")
|
2026-03-07 10:29:17 +08:00
|
|
|
flask_app = Flask(__name__)
|
|
|
|
|
flask_app.config.from_object(config_by_name[config_name])
|
2026-03-07 09:01:00 +08:00
|
|
|
|
2026-03-07 10:29:17 +08:00
|
|
|
CORS(flask_app, resources={r"/api/*": {"origins": "*"}}, supports_credentials=True)
|
|
|
|
|
db.init_app(flask_app)
|
|
|
|
|
migrate.init_app(flask_app, db)
|
|
|
|
|
jwt.init_app(flask_app)
|
|
|
|
|
limiter.init_app(flask_app)
|
|
|
|
|
socketio.init_app(flask_app, message_queue=flask_app.config.get("CELERY_BROKER_URL") or None)
|
2026-03-07 09:01:00 +08:00
|
|
|
|
2026-03-07 10:29:17 +08:00
|
|
|
flask_app.redis = Redis.from_url(flask_app.config["REDIS_URL"]) if flask_app.config.get("REDIS_URL") else None
|
2026-03-07 09:01:00 +08:00
|
|
|
|
|
|
|
|
from app.api import register_blueprints
|
2026-03-07 10:29:17 +08:00
|
|
|
register_blueprints(flask_app)
|
|
|
|
|
|
|
|
|
|
from app.admin_login_routes import register_admin_login_routes
|
|
|
|
|
register_admin_login_routes(flask_app) # /admin-login、/admin-logout
|
2026-03-07 09:01:00 +08:00
|
|
|
|
|
|
|
|
import app.socket_events # noqa: F401 - register SocketIO handlers
|
|
|
|
|
|
2026-03-07 10:29:17 +08:00
|
|
|
with flask_app.app_context():
|
|
|
|
|
try:
|
|
|
|
|
from app.utils.ensure_admin import ensure_admin_user
|
|
|
|
|
ensure_admin_user() # 默认管理员 admin / 123456
|
|
|
|
|
except Exception as e:
|
|
|
|
|
import warnings
|
|
|
|
|
warnings.warn(f"ensure_admin_user skipped: {e}", UserWarning)
|
|
|
|
|
|
|
|
|
|
# Flask-Admin 在 create_app 内初始化会因包名 app 冲突失败,改在 run.py 中初始化
|
|
|
|
|
# try:
|
|
|
|
|
# from app.admin import init_admin
|
|
|
|
|
# init_admin(flask_app)
|
|
|
|
|
# except Exception as e:
|
|
|
|
|
# import warnings
|
|
|
|
|
# warnings.warn(f"Flask-Admin init skipped: {e}", UserWarning)
|
2026-03-07 09:01:00 +08:00
|
|
|
|
2026-03-07 10:29:17 +08:00
|
|
|
@flask_app.route("/health")
|
2026-03-07 09:01:00 +08:00
|
|
|
def health():
|
|
|
|
|
return {"status": "healthy"}, 200
|
|
|
|
|
|
2026-03-07 10:29:17 +08:00
|
|
|
return flask_app
|