You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
iTi-Flask/iti/applications/__init__.py

104 lines
3.0 KiB
Python

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import os
import warnings
from apiflask import APIFlask
from iti.applications.common.utils.schema import custom_schema_name_resolver
from iti.applications.service import init_services
from .extensions import init_exts
from .routes import init_routes
from ..config import get_config
from .events import init_event_handlers
def create_app(config_name=None):
"""
应用工厂函数
Args:
config_name: 配置名称 ('dev', 'test', 'prod')
如果为 None则从环境变量 FLASK_ENV 读取
Returns:
Flask 应用实例
docs_ui: The UI of API documentation, one of `swagger-ui` (default), `redoc`,
`elements`, `rapidoc`, and `rapipdf`.
"""
# 忽略 apispec 的 schema 名称冲突警告
warnings.filterwarnings(
"ignore",
message="Multiple schemas resolved to the name",
category=UserWarning,
module="apispec.ext.marshmallow.openapi",
)
app = APIFlask(
__name__.split(".")[0],
title="iTi-Flask",
version="1.0.0",
json_errors=True,
docs_ui="elements",
)
# 加载配置
config_obj = get_config(config_name)
app.config.from_object(config_obj)
# 配置自定义 schema 名称解析器
# 参考https://zh.apiflask.com/schema/#%E6%A8%A1%E5%BC%8F%E5%90%8D%E7%A7%B0%E8%A7%A3%E6%9E%90%E5%99%A8
# 用于解决循环引用和嵌套 schema 导致的命名冲突警告
app.schema_name_resolver = custom_schema_name_resolver
# 确保必要的目录存在
_ensure_directories(app)
# 使用第三方JWT自定义Security避免doc无法传递header
# 等同于 SECURITY_SCHEMES 配置
app.security_schemes = {
"JWT": {
"type": "apiKey",
"in": "header",
"name": "Authorization",
}
}
# 保护doc文档鉴权后才可访问
# app.config['SPEC_DECORATORS'] = [jwt_required()]
# app.config['DOCS_DECORATORS'] = [jwt_required()]
# 初始化扩展
init_exts(app)
# 初始化事件处理器
init_event_handlers(app)
# 初始化路由
init_routes(app)
# 初始化Services
init_services(app)
# 打印当前环境信息
env = config_name or os.getenv("FLASK_ENV", "dev")
print(f"🚀 应用启动 - 环境: {env}")
print(f"📊 数据库: {app.config.get('SQLALCHEMY_DATABASE_URI')}")
return app
def _ensure_directories(app):
"""确保必要的目录存在"""
# 数据库目录SQLite
db_uri = app.config.get("SQLALCHEMY_DATABASE_URI", "")
if "sqlite:///" in db_uri and not db_uri.endswith(":memory:"):
db_path = db_uri.replace("sqlite:///", "")
db_dir = os.path.dirname(db_path)
if db_dir and not os.path.exists(db_dir):
os.makedirs(db_dir, exist_ok=True)
file_storage_config = app.config.get("FILE_STORAGE", {})
local_config = file_storage_config.get("LOCAL", {})
local_path = local_config.get("base_path")
if local_path:
os.makedirs(local_path, exist_ok=True)