Skip to content

一个Flask手脚架工具,集成一些在开发生产时非常有用的功能

Notifications You must be signed in to change notification settings

monklof/flaskproject-in-production

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

flaskproject-in-production

FIP(Flaskproject-in-production)

FIP是什么?

这是一个较小的Flask Demo,集成了一些在基于Flask开发部署Web应用时非常有用的功能,基于它,你可以快速开始写一个Flask应用并应用到生产环境下。

Flask本身是一个轻量级的Web框架,提供了Web请求处理的基本框架,能帮助开发者解决许多在HTTP请求处理层面上的许多问题。但在实际的工程中,我们往往需要做更多的工作来使得基于Flask的应用能够应用到生产环境下。譬如:

  • 用户认证: 有些资源/页面访问时需要进行认证,而这个过程其实是比较通用的,能否把这个功能集成好呢?
  • 程序配置管理: 线下开发和线上部署时程序往往要使用不同的配置(比如常见的情况就是线下开发需要指向线下数据库,而线上需要指向线上数据库),能否提供一种通用的配置方式呢?使得程序可以方便的进行配置切换?
  • 生产环境下的部署: Flask自带的调试server是单线程的,一个请求阻塞后之后的请求都会被卡住,在生产环境下肯定不能使用这个server。通常我们会选择使用Gunicorn这样的服务器来作为生产环境下的并发方案,这个功能也可以集成起来。
  • 日志文件管理: 在生产环境下,往往要记录程序的访问日志、出错日志、应用日志以方便进行问题定位。而Flask是没有提供这样的机制的,往往还需要开发者再去开发这样的功能。

我相信这些功能,是一个健康成熟的线上生产应用的通用需求。FIP将这些功能集成起来,以方便开发者开发时,不再需要再关注这些通用性的问题,而将关注点切换至更高层次上解决问题,提高开发效率。

功能特性

目前实现上采用SQLAlchemy,作为关系型数据库的ORM,gunicorn用来作为生产服务器。

用户认证

FIP集成了用户认证功能,实现上采用Flask插件Flask-Login作为认证管理工具。

具体功能包括: 用户登录、用户注册、用户认证。

相关实现代码在src/auth.py中。

用户认证

假设页面/home需要登录后的用户在才能访问,那么你可以这样使用,当用户未登录时,会自动跳转到登录页面/login中:

from auth import flask_login
...

@app.route("/home")
@flask_login.login_required
def home():
    return render_template("home.html")

用户登录与用户注册

FIP简单实现了一个用户登录和注册功能,你可以在src/auth.py中进行自定义。

  • /login: 登录
  • /register: 注册

多版本配置管理

FIP使用一个多版本配置工具Swing来管理配置,在src/settings.py中,可以很方便的配置多个版本的配置。

  • DevleopmentConfig类中配置开发环境的配置
  • ProductionConfig中配置生产环境配置
  • 通过swing.config的属性,能访问对应的配置项。
  • 使用管理脚本src/manage.py的命令行参数便能很方便的控制程序运行在哪个配置上。这个会在后面说明。
from swing import ConfigBase

class CommonConfig(ConfigBase):

    SECRET_KEY = "the secret key (you should change this!)"
    DEBUG = True
    DB_CONNECTION = "sqlite:///flask.db"
    # ... 

class DevelopmentConfig(CommonConfig):
    __confname__ = "dev"

class ProductionConfig(CommonConfig):
    __confname__ = "prod"
    DEBUG = False
    DB_CONNECTION = "sqlite:///flask.prod.db"

集成部署方案

内嵌Gunicorn的部署方案,Gunicorn使用pre-fork worker模型来作为并发策略。部署时,他会启动多个Worker进行来接收处理请求。使得服务能力远比Flask自带的调试服务器能力强。

集成日志管理

对Web请求访问日志、出错日志、程序出错日志都做了对应的集成,你只需要在src/settings.py中更改这些日志的位置,或者通过bin/manage.py启动应用时显示指定日志位置就可以将日志打到指定的位置。

其他特性

  1. 支持静态文件链接带hash tag: 构建静态文件url时,会对文件进行hash处理,将tag加到url参数中,这样方便进行静态文件更新而无需手动更新文件hash tag。

快速开始

安装环境

$ git clone https://github.com/monklof/flaskproject-in-production.git
$ cd flaskproject-in-production
$ sudo pip install -r requirements.txt

manage.py

manage.py是FIP的管理命令,它有两个子命令:

  • debug_server: 启动Flask内置的调试服务器运行应用。
  • gunicorn_server: 使用Gunicorn来启动服务器运行应用。
$ ./bin/manage.py debug_server

这样便会启动一个5000端口的Flask内嵌Server,运行在Debug模式,使用开发环境下的配置。访问 http://localhost:5000/ 便可以浏览一个简单支持登录注册权限验证的demo。

如果在生产环境下,需要更加健壮的并发策略时,可以这样使用:

$ ./bin/manage.py gunicorn_server accesslog=/path/to/accesslog/access.log errorlog=/path/to/errorlog 

这样,会默认启动2*N + 1个worker进程数来接收请求处理,N为CPU核数。使用gunicron_server会默认使用生产环境配置。

命令行参数

manange.py支持以下参数:

  • manange.py debug_server

    • --config=${CONFIG}: 使用程序的哪个配置, 默认是dev
    • --host=${HOST}: server绑定在哪个IP上,默认是0.0.0.0
    • --port=${PORT}: server端口,默认是5000
  • manage.py gunicorn_server

    • --config=${CONFIG}: 使用程序的哪个配置, 默认是prod
    • --host=${HOST}: server绑定在哪个IP上,默认是0.0.0.0
    • --port=${PORT}: server端口,默认是5000
    • --workers=${WORKERS}: 启动worker进程数,默认是2*N+1,N为CPU核心数。
    • --accesslog=${ACCESSLOG}: Web访问日志文件
    • --errorlog=${ERRORLOG}: 出错日志文件

内部实现

目录结构

  • bin/manage.py: 运行应用的命令接口。

  • package.json: 前端框架依赖

  • requirements.txt: Python依赖包

  • webpack.config.js: 前端js打包的webpack配置

  • src/: 主代码目录

    • main.py: 程序入口
    • fe-src/js: js源代码
    • static/: 静态文件
    • templates/: 模板
    • auth.py: 认证相关代码
    • model.py: 程序使用的一些数据库实体
    • api.py: 提供了一个用于演示的api接口
    • settings.py: 程序使用的配置
    • utils/: 使用的一些工具

参考

  • Swing by @monklof , 在此项目中用来进行配置管理。
  • docopt by @ekayxu , 在此项目中用来进行命令行解析。

作者

License

MIT

About

一个Flask手脚架工具,集成一些在开发生产时非常有用的功能

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published