app.py 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. """Quart + Hypercorn 应用工厂 —— 全局配置驱动,DB + 日志 + XXL-JOB 生命周期内建"""
  2. import logging
  3. from quart import Quart
  4. from quart_cors import cors
  5. from supply.core.bootstrap import AppContext
  6. from supply.config import GlobalConfig
  7. from supply.infra.database.manager import DatabaseManager, create_backend
  8. from supply.infra.observability.logging import LogService
  9. from supply.infra.xxl_jobs import XxlJobExecutor
  10. from supply.handlers import discover_and_register
  11. from supply.server.xxl_endpoints import set_xxl_executor
  12. logger = logging.getLogger(__name__)
  13. def create_app(global_config: GlobalConfig = None) -> Quart:
  14. """创建 Quart 应用
  15. 统一从 GlobalConfig 获取所有配置,消除散落的 Config() 调用。
  16. 可选传入 custom_config 用于测试覆盖。
  17. Args:
  18. global_config: 可选的自定义配置,默认从环境变量加载
  19. """
  20. if global_config is None:
  21. global_config = GlobalConfig()
  22. logging.basicConfig(level=logging.INFO)
  23. # 初始化各层依赖 —— 全部从 global_config 取值
  24. log_service = LogService(global_config.aliyun_log)
  25. db = DatabaseManager(
  26. {
  27. name: create_backend(name, config)
  28. for name, config in global_config.active_db_configs().items()
  29. }
  30. )
  31. discover_and_register()
  32. xxl_executor = XxlJobExecutor(global_config.xxl_job)
  33. set_xxl_executor(xxl_executor)
  34. app = Quart(__name__)
  35. app = cors(app, allow_origin="*")
  36. # 生命周期
  37. ctx = AppContext()
  38. ctx.on_startup(log_service.start)
  39. ctx.on_startup(db.init_pools)
  40. ctx.on_startup(xxl_executor.start)
  41. ctx.on_shutdown(xxl_executor.stop)
  42. ctx.on_shutdown(db.close_pools)
  43. ctx.on_shutdown(log_service.stop)
  44. @app.before_serving
  45. async def startup():
  46. logger.info("Starting application...")
  47. await ctx.start_up()
  48. logger.info("Application started successfully")
  49. @app.after_serving
  50. async def shutdown():
  51. logger.info("Shutting down application...")
  52. await ctx.shutdown()
  53. logger.info("Application shutdown successfully")
  54. return app