config.py 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. import os
  2. from datetime import timedelta
  3. from urllib.parse import parse_qsl, urlencode, urlparse, urlunparse
  4. def mysql_uri_with_utf8mb4(uri: str) -> str:
  5. """为 MySQL 连接补上 charset=utf8mb4,避免中文姓名等写入变成 ??。"""
  6. if not uri or 'mysql' not in uri.split('://', 1)[0].lower():
  7. return uri
  8. parsed = urlparse(uri)
  9. params = dict(parse_qsl(parsed.query, keep_blank_values=True))
  10. if params.get('charset', '').lower() not in ('utf8', 'utf8mb4'):
  11. params['charset'] = 'utf8mb4'
  12. query = urlencode(params)
  13. return urlunparse(parsed._replace(query=query))
  14. class Config:
  15. SECRET_KEY = 'WZY' # Flask 密钥,用于签名 cookies 和其他需要加密的操作
  16. # 支援 Docker:以環境變數覆寫(建議使用 mysql+pymysql://...)
  17. SQLALCHEMY_DATABASE_URI = mysql_uri_with_utf8mb4(
  18. os.environ.get(
  19. 'SQLALCHEMY_DATABASE_URI',
  20. 'mysql://root:YHJYgain9420.@localhost/bridge_disease',
  21. )
  22. ) # SQLAlchemy 数据库 URI
  23. SQLALCHEMY_TRACK_MODIFICATIONS = False # 禁用 SQLAlchemy 的修改追踪
  24. ALLOWED_IMAGE_EXTENSIONS = {'png', 'jpg', 'jpeg'} # 允许上传的图片文件扩展名
  25. ALLOWED_VIDEO_EXTENSIONS = {'mp4'} # 允许上传的视频文件扩展名
  26. ALLOWED_MODEL_EXTENSIONS = {'pt'} # 允许上传的模型文件扩展名
  27. AVATARS_FOLDER = os.path.join(os.getcwd(), 'app', 'static', 'avatars') # 头像存储的文件夹路径
  28. MODELS_FOLDER = os.path.join(os.getcwd(), 'app', 'static', 'models') # 模型存储的文件夹路径
  29. MEDIAS_FOLDER = os.path.join(os.getcwd(), 'app', 'static', 'medias') # 媒体存储的文件夹路径
  30. RESULTS_FOLDER = os.path.join(os.getcwd(), 'app', 'static', 'results') # 结果存储的文件夹路径
  31. DATASETS_FOLDER = os.path.join(os.getcwd(), 'data', 'datasets') # YOLO 训练数据集
  32. TRAINING_RUNS_FOLDER = os.path.join(os.getcwd(), 'data', 'training_runs') # Ultralytics 训练输出
  33. TRAINING_META_FOLDER = os.path.join(os.getcwd(), 'data', 'training_meta') # 任务/数据集元数据 JSON
  34. MAX_AVATAR_SIZE = 5 * 1024 * 1024 # 最大头像文件大小:5MB
  35. MAX_DATASET_ZIP_SIZE = 500 * 1024 * 1024 # 数据集 ZIP 上限 500MB
  36. # HS256 需足夠長的密鑰;過短會觸發 PyJWT InsecureKeyLengthWarning,且驗證可能失敗(客戶端 422)
  37. JWT_SECRET_KEY = os.environ.get(
  38. 'JWT_SECRET_KEY',
  39. 'bridge-disease-dev-jwt-secret-min-32-chars-change-me',
  40. )
  41. JWT_ACCESS_TOKEN_EXPIRES = timedelta(hours=1) # access token 过期时间
  42. JWT_REFRESH_TOKEN_EXPIRES = timedelta(days=30) # refresh token 过期时间
  43. CRACK_SCALA_FACTOR = 0.1 # 裂缝缩放因子
  44. # 病害指标权重配置
  45. DISEASE_INDEX_WEIGHTS = {
  46. 'disease_count': 0.15,
  47. 'disease_perimeter': 0.15,
  48. 'disease_area': 0.2,
  49. 'shape_complexity': 0.15,
  50. 'texture_roughness': 0.15,
  51. 'crack_width': 0.1,
  52. 'avg_hue': 0.1,
  53. }
  54. # API 限流配置
  55. RATE_LIMIT_DEFAULT_LIMIT = 60 # 默认每分钟允许的请求次数
  56. RATE_LIMIT_DEFAULT_PERIOD = 60 # 默认限流时间窗口(s)