# initialization-WSGI应用工厂

initialization

initialization 属于应用基础的一部分。如果把 configs/ 看做是设计的蓝图,那么 initialization/ 就是工厂,它的目的就是根据蓝图为我们打造WSGI应用。

在该文件夹下,存放着以 _process.py 结尾的初始化器文件,可以把他们看做是工厂中的车间,不同的车间对 WSGI 应用特定的功能负责。

脚手架工具一章中我们介绍到,脚手架工具提供了一些可选的初始化器文件,如果选择了,会在 initialization/ 下添加对应的 _process.py 文件,并且在 initialization/__init__.py 进行启用。

通过预置的初始化器,开发者可以通过简单的配置开心得与达观 SDK 或者效率工具进行集成。

因此后续初始化器会不断更新。

WARNING

对于可选的初始化器,在 _process.py 文件开头都标有说明注释。如果没有可以参考选择初始化器时的 gitlab/wiki 链接。

特殊的。对于 Flask-Boot 来说,目前有两个重要的初始化器,任何项目都必须依赖这两个初始化器,他们分别是 config_process.pylogger_process.py

# config_process.py

统一配置一章中提到,app.yml 的加载依赖 config_process.py 初始化器。

config_process.py 所做的事情也并不神秘,它:

  1. 引入 dg-sdk-env-config 并自动加载 configs/app.yml 文件

  2. 将 flask section 下的所有配置大写对 Flask.config 进行 update

  3. 加载所有的 Boot 配置,并放入 Flask.config["BOOT"]

    比如 global_conf 可以通过 Flask.config["BOOT"]["global_conf"] 获取

# logger_process.py

日志初始化器帮助开发者进行了默认的日志配置。

在业务代码中,尽量使用 logger_process.py 创建出来的 logger 对象(也可以使用app.logger,这俩是一个东西)

比如:

from {{my_flask_name}}.initialization.logger_process import logger

logger.info("info")
logger.warn("warning")

日志初始化器做了这么几件事:

  1. 对 app.logger 配置了统一的日志输出格式
  2. 如果安装了 loguru 则对 app.logger 和 werkzeug 日志都做了增强
  3. 设置了日志等级为 INFO

详见 模板如何处理logger 一节

# 自定义初始化器

除了脚手架工具提供的初始化器外,开发者还可以添加任何自定义的初始化器。

比如项目上希望使用Sentry来监控Flask app的报错日志,可以遵循下面几个步骤来添加:

  1. 添加配置:

    在 app.yml 中添加相关的配置

    sentry:
        enable: True
        sentry_dns: sentry.datagrand.com
    
  2. 创建文件

    创建一个sentry_process.py的车间文件,添加如下实现,最好添加相关说明

    """
    相关说明
    """
    from . import app
    
    sentry_config = app.config.get("BOOT", {}).get("sentry", {})
    
    if sentry_config.get("enable") and sentry_config.get("sentry_dns"):
        import sentry_sdk
        from sentry_sdk.integrations.flask import FlaskIntegration
    
        # init sentry sdk
        sentry_sdk.init(dsn=sentry_config['sentry_dns'], integrations=[FlaskIntegration()])
    
        # 手动触发sentry debug
        @app.route('/debug-sentry')
        def trigger_error():
            1 / 0
    
  3. 导入

    最后,为了启用这个车间,必须在 __init__.py 文件中的 _init 方法中进行导入(见下面一节)

# __init__.py

__init__.py文件由三个函数组成,_init_auto_register_blueprintscreate_app

  • _init 方法,所有的初始化器定义完毕后,应该显式地在 _init 方法中进行导入,以告诉其他开发者本项目所依赖的全部初始化器。

    注意! 导入的顺序十分重要,就像不同车间生产时,一些车间依赖前面车间的工作。

    比如 config_process 应该早于任何一个初始化器来加载。

    def _init(app: Flask):
        """
        对 Flask 应用进行初始化
        """
        from . import (
            config_process,
            logger_process,
        )
    
  • _auto_register_blueprints 方法可以自动导入蓝图。

    开发者也可以手动去修改,以导入需要的蓝图。

    注意,开发者需要在 resources/__init__.py 中将所有定义好的蓝图进行 import ,这样才能被自动注册,如:

    # resources/__init__.py
    from .my_resource import my_blueprint
    
    __all__ = [
        "my_blueprint"
    ]
    

    详见技术分层

  • create_app 方法,整个工厂的入口函数。