环境安装
# 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为例进行讲解
项目结构
flask_test
- apps: 存放各个蓝图模块
- app01
- init.py存放蓝图的配置
- init.py 存储flask项目的配置
- extensions.py 存放SQLAlchemy的配置
- scheduler.py 存放定时任务的配置
- app01
- 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
参考文档: