__init__.py 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. import os
  2. from datetime import datetime
  3. from logging.config import dictConfig
  4. from flask import Flask
  5. from flask_cors import CORS
  6. from .config import Config
  7. from .errors import *
  8. from .models import init_db
  9. from .routes import register_routes
  10. from .utils import init_jwt
  11. from .utils.rate_limiter import configure_rate_limiting
  12. def create_app():
  13. """
  14. 创建和配置 Flask 应用实例。
  15. :return: 配置好的 Flask 应用实例
  16. :rtype: Flask
  17. """
  18. app = Flask(__name__, instance_relative_config=True)
  19. # 启用 CORS 支持
  20. CORS(app)
  21. # 配置日志记录
  22. configure_logging()
  23. # 加载配置
  24. app.config.from_object(Config)
  25. app.logger.info(f'初始化服务配置:{dict(app.config)}')
  26. # 初始化 JWT
  27. init_jwt(app)
  28. # 初始化数据库
  29. init_db(app)
  30. # 注册蓝图
  31. register_routes(app)
  32. # 配置 API 限流 - 只使用内存存储作为限流后端
  33. configure_rate_limiting(app)
  34. # 注册全局错误处理器
  35. register_error_handlers(app)
  36. return app
  37. def configure_logging():
  38. """
  39. 配置日志记录。
  40. 创建一个名为 'logs' 的文件夹(如果不存在),并配置日志记录的格式和处理器。
  41. 日志记录将保存到 'logs' 文件夹中一个以时间戳命名的文件中,以确保每次运行时都有一个新的日志文件。
  42. 日志记录器包括:
  43. - `StreamHandler` 用于输出到控制台(WSGI 错误流)
  44. - `FileHandler` 用于将日志写入文件
  45. :return: None
  46. """
  47. log_folder = 'logs'
  48. if not os.path.exists(log_folder):
  49. os.makedirs(log_folder)
  50. timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
  51. log_filename = os.path.join(log_folder, f'app_{timestamp}.log')
  52. dictConfig({
  53. 'version': 1,
  54. 'formatters': {
  55. 'default': {
  56. 'format': '[%(asctime)s] %(levelname)s at %(filename)s:%(lineno)d: %(message)s',
  57. 'datefmt': '%Y-%m-%d %H:%M:%S'
  58. }
  59. },
  60. 'handlers': {
  61. 'wsgi': {
  62. 'class': 'logging.StreamHandler',
  63. 'stream': 'ext://flask.logging.wsgi_errors_stream',
  64. 'formatter': 'default'
  65. },
  66. 'file': {
  67. 'class': 'logging.FileHandler',
  68. 'filename': log_filename,
  69. 'formatter': 'default',
  70. 'encoding': 'utf-8',
  71. 'level': 'DEBUG'
  72. }
  73. },
  74. 'root': {
  75. 'level': 'DEBUG',
  76. 'handlers': ['wsgi', 'file']
  77. }
  78. })