Flask 蓝图框架搭建

159 阅读4分钟

环境安装

# flask依赖包
pip install Flask
# flask于RestFul集成的包
pip install Flask-RESTful
# flask的orm集成框架
pip install Flask-pymysql
pip install Flask-SQLAlchemy
# 定时任务
pip install Flask-APScheduler

下面项目以flask-test为例进行讲解

项目结构

image.png

flask_test

  • apps: 存放各个蓝图模块
    • app01
      • init.py存放蓝图的配置
    • init.py 存储flask项目的配置
    • extensions.py 存放SQLAlchemy的配置
    • scheduler.py 存放定时任务的配置
  • conf: 存放项目的配置文件
    • application.yaml
  • middleware 存放中间件的配置
    • request_middleware.py 存放项目的中间件设置,如: before_request、after_request等
  • sdk 存放一些第三方包,例如:
    • 日志相关
    • http请求相关
    • es相关
  • utils 存放项目中公共的工具类
  • app.py flask应用的初始化文件,也是入口文件
  • gunicorn_config.py 存放flask部署时的gunicorn配置
  • settings.py 存放整个flask项目的配置

项目配置

蓝图配置

在apps/app01/init.py下进行设置

from flask import Blueprint
from flask_restful import Api

app01 = Blueprint('metrics_monitor', __name__,
                  url_prefix='/api/v1/app01',
                  template_folder='templates',
                  static_folder='static',
                  static_url_path='assets')

api = Api(app01)

应用配置

  • 在apps下的__init__.py中配置create_app用于创建flask应用
from flask import Flask

from apps.app01 import app01
from apps.extensions import db


def create_app():
    """
    app的初始化
    :return:
    """
    app = Flask(__name__)
    # 加载配置
    app.config.from_object('settings')
    # 初始化app
    db.init_app(app)
    # 添加蓝图
    app.register_blueprint(app01)

    return app
  • 在app.py 中配置app的初始化
from apps import create_app

# 创建flask的app
app = create_app()


if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8080, debug=True)

SQLAlchemy配置

  • 在apps/extensions.py下配置
from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()
  • 使用时直接在各个蓝图的model中引入即可
from apps.extensions import db

项目的全局配置 settings.py

项目在启动的时候,会优先加载settings.py中的配置

  • 包括日志配置
  • 数据库相关的配置
  • 定时任务配置等
import os
import logging.config
from pathlib import Path
from utils.config_parser import ConfigParser

BASE_DIR = Path(__file__).resolve().parent

# application.yaml 本地配置文件路径
# 测试环境配置
APPLICATION_CONFIG_PATH = os.path.join(BASE_DIR, 'conf', 'application.yaml')

# 日志配置,根据项目需要自己配置
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'file_formatter': {
            'format': '[%(asctime)s][%(threadName)s:%(thread)d][%(filename)s[line:%(lineno)d][%(levelname)s] - '
                      '%(message)s'
        },
        'simple': {
            'format': '[%(asctime)s][%(levelname)s] - %(message)s'
        },
    },
    'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
            'formatter': 'simple',
            'level': 'DEBUG'
        },
    },
    'loggers': {
        'flask_logger': {
            'handlers': ['console'],
            'level': 'INFO',  # 设置日志级别,可以根据需要调整
            'propagate': False,
        },
        'sqlalchemy': {
            'handlers': ['console'],
            'level': 'INFO',
            'propagate': False,
        }
    },
}

# 加载日志
logging.config.dictConfig(LOGGING)

# 数据库配置
user, password, port, host, database, charset = config_parser.get_mysql_set()
SQLALCHEMY_DATABASE_URI = f"mysql+pymysql://{user}:{password}@{host}:{port}/{database}?charset={charset}"

基于以上的配置,可以完成flask蓝图的基本使用

高级配置

中间件配置

  • 在middleware下的request_middleware.py编写中间件的逻辑
    • before_reuest  请求前的逻辑
    • after_request  请求后的逻辑
def before_request():
    # 编写请求前的逻辑
    print('before_rqeuest')


def after_request(response):
    # 编写请求后的逻辑
    print('after request')

    return response
  • 逻辑编写完后,需要在app.py中配置中间件的接入
# 注册请求前后的中间件
app.before_request(before_request)
app.after_request(after_request)

全局异常配置

  • 编写全局异常的处理逻辑
from flask import jsonify


def handle_ex(error):
    return jsonify({"code": -1, "msg": f"{error}"})
  • 在app.py 中进行注册
# 注册全局异常处理
app.register_error_handler(Exception, handle_ex)
  • 如果使用flask-restful,则需要在各个蓝图中配置,当前项目需要在app01/init.py中配置
# flask-restful 需要在子蓝图中 定义handler_error,走到全局异常中去,否则会进入到flask-restful自己的异常处理中
api.handle_error = handle_ex

定时任务配置

注意:本项目使用的是APScheduler,一定要安装Flask-APScheduler

  • 在apps/scheduler.py中配置APScheduler
from flask_apscheduler import APScheduler

# 默认就是后台调度模式
scheduler = APScheduler()
  • 在app.py中初始化定时任务
# 初始化定时任务并启动定时任务
scheduler.init_app(app)
scheduler.start()
  • 配置定时任务(在settings.py中配置)
# #################配置定时任务################
JOBS = [
    {
        'id': 'xxx',
        # 包名:方法名
        'func': 'apps.app01.tasks:test_job1',
        'trigger': 'interval',
        # 每60s执行一次
        'seconds': 60
    }
]

# 开启flask-apsscheduler的api
SCHEDULER_API_ENABLED = True
# ###########################################

具体定时任务可以参考:

Flask教程(18)--flask-apscheduler - 掘金

项目部署

  • 在gunicorn_config.py文件中配置相关信息
# 是否开启debug模式
debug = False
# 访问地址
bind = "0.0.0.0:8080"
# 工作进程数
workers = 2
# 工作线程数
threads = 2
# 超时时间
timeout = 600
# 输出日志级别
# gunicorn + apscheduler场景下,解决多worker运行定时任务重复执行的问题
preload_app = True
  • 启动命令
gunicorn -c config.py app:app
  • 用supervisord配置启动
[supervisord]
nodaemon=true
logfile=/var/log/supervisor/supervisord.log
pidfile=/var/run/supervisor/supervisord.pid
logfile_maxbytes=100MB
logfile_backups=10

[unix_http_server]
file=/var/run/supervisor/supervisor.sock
chmod=0777

[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface

[supervisorctl]
serverurl=unix:///var/run/supervisor/supervisor.sock

[program:flask_test]
command=gunicorn -c config.py app:app
directory=/opt/code/flask_test
autostart=true
autorestart=true
redirect_stderr=true
stdout_logfile=/var/log/flask_test/stdout.log
stderr_logfile=/var/log/flask_test/stderr.log

参考文档:

gunicorn 部署flask项目 - 三只松鼠 - 博客园