Welcome to guniflask 0.12.18

Overview

guniflask是自动化生成基于flask + gunicorn的服务端项目基础代码的构建工具。

Table of Contents

Running guniflask

首先安装guniflask项目生成工具guniflask-cli用于自动化构建项目的基础代码:

$ pip install -U guniflask-cli

创建项目目录,并运行guniflask的初始化项目命令:

$ mkdir your_project && cd your_project
$ guniflask init

其中 your_project 表示项目名称。 接下来会以对话的形式完成项目的初始配置,当选择默认设置时直接按Enter键即可。

根据导引完成配置之后,会在项目根目录下生成项目的初始代码。

如果生成和文件和原文件产生了冲突,则会有如下提示:

? Overwrite some_file_here? (Y/n/a/x)

这里可以输入如下指令:

  • y : 覆盖该文件 (默认选项)

  • n : 跳过该文件

  • a : 覆盖该文件以及所有后续冲突的文件

  • x : 中止操作

最后,生成完所有项目文件后会提示项目创建成功。

Warning

建议在运行guniflask前使用Git等版本控制工具保存当前项目的所有更改,以免在生成项目文件的过程中替换了未保存的更改。

Configuration

Overview

配置包括两部分,一部分是gunicorn配置,另一部分是app配置。 gunicorn配置主要是对HTTP Server的配置。 app配置主要是业务相关的配置。

部分配置也可以通过环境变量设定,环境变量的优先级高于配置文件。

Gunicorn Configuration

我们可以在 conf/gunicorn.py 中通过定义变量的方式添加gunicorn配置项,包括但不限于:

  • bind: 项目运行时绑定的地址

  • loglevel: 日志级别

gunicorn详细的配置项可参考gunicorn文档: http://docs.gunicorn.org/en/stable/settings.html

项目默认的gunicorn配置项:

  • daemon: True

  • workers: os.cpu_count()

  • pidfile: 默认存放在项目根目录下的 .pid 文件夹中

  • accesslog: 默认存放在项目根目录下的 .log 文件夹中

  • errorlog: 默认存放在项目根目录下的 .log 文件夹中

Application Configuration

我们在 conf/app.env 中定义应用启动时加载的环境变量。

我们在 conf/your_project.py 中通过定义变量的方式添加配置项,包括系统功能配置、项目自定义配置等。有关配置项的获取、内置配置项等详细信息可参考 Application Settings

Multiple Profiles

在实际开发过程中,根据运行环境的不同我们可能需要不同的配置文件。 例如,在生产环境中和开发环境数据库相关的配置往往不同。

我们通过引入profile的概念来区别不同的运行环境。 例如,我们设定两个profile——prod和dev,分别对应生产环境和开发环境。 那么我们可以在 conf/your_project_prod.py 中声明生产环境下的项目配置,在 conf/your_project_dev.py 中声明开发环境下的项目配置。 环境变量配置和gunicorn配置同样可以用profile后缀加以区分, conf 目录下配置文件的组织形式如下:

conf/
    app.env
    app_dev.env
    app_prod.env
    gunicorn.py
    gunicorn_dev.py
    gunicorn_prod.py
    your_project.py
    your_project_dev.py
    your_project_prod.py

Application Settings

项目的配置项在 conf/your_project.py 文件中定义。 针对不同运行环境可以通过指定profile实现项目配置的切换,详见 Multiple Profiles

Uppercase Settings

定义的uppercase形式的配置项,如 SQLALCHEMY_DATABASE_URI ,会被认为是Flask相关的配置项,并在init app之前自动注入到 app.config 中。

Getting Settings

我们可以通过如下方式获取项目配置:

from guniflask.config import settings

settings 中存放着项目所有的配置项, settings 是一个实现了 MutableMapping 接口的对象。 我们可以通过 setings['key'] 的方式获取配置项 key 的属性值,如果 key 不存在则返回 None

Built-in Settings

内置的配置项会在加载配置文件前自动填充。

home

项目的根目录。

app_name

运行的应用的名称,可以通过环境变量 GUNIFLASK_APP_NAME 指定运行的应用。

active_profiles
  • Default: None

指定激活哪些profile。 可以通过环境变量 GUNIFLASK_ACTIVE_PROFILES 进行设置,或通过 debug/start 命令的 -p 选项进行设置。 有关使用profile区别运行环境并加载不同配置的详细信息请参考 Multiple Profiles

debug
  • Default: None

是否为debug模式。 可以通过环境变量 GUNIFLASK_DEBUG 进行设置,在执行 debug 命令会自动设置。

host

应用运行时绑定的地址。

port

应用运行时绑定的端口。

ip_address

应用所在的主机的IP地址。

Settings to Configure the Built-in Features

我们在名为 guniflask 的dict对象下配置guniflask提供的内置功能。 可用的配置项包括:

cors

跨域相关配置。

table2model_dest
  • Default: 'your_project/models'

配置table2model生成结果存储的模块路径,路径为相对于项目根目录的相对路径。 默认存储在项目根模块下的 models 模块中。

Application

your_project.app 模块中我们定义应用运行所需的Flask插件,同时提供若干钩子函数,会在项目运行生命周期的不同阶段进行调用。 系统自动生成的插件会自动完成初始化操作,我们额外引入的插件需要在 init_app() 中实现初始化。

make_settings(app, settings)
Parameters
  • app – Flask app

  • settings – 项目配置

此函数会在读取完配置文件后进行调用。

init_app(app, settings)
Parameters
  • app – Flask app

  • settings – 项目配置

此函数可用于初始化Flask和及其扩展。

Blueprints

Blueprint Concept

Flask提供了blueprint的概念用于模块化构建服务端代码,详细文档可参考Flask文档: http://flask.pocoo.org/docs/blueprints/

Declaring Blueprint

项目用到的 Blueprint 可以在任意位置进行声明,项目启动时会自动将所有声明的 Blueprint 自动注册到Flask app中。

Using @blueprint

我们可以使用装饰器来替代显示的声明 Blueprint 。 下面的代码给出了一个运算加法的接口的示例。

from flask import request

from guniflask.web import blueprint, post_route


@blueprint('/api')
class MathController:
    def __init__(self):
        self.add_service = lambda a, b: a + b

    @post_route('/add')
    def add(self):
        data = request.json
        return {'result': self.add_service(data.get('a'), data.get('b'))}

Database & ORM

Database Access

项目默认基于Flask-SQLAlchemy实现对数据库的访问,生成项目文件 your_project/app.py 中包含了 SQLAlchemy 对象的初始化方式,在项目其他位置可以通过如下方式获取该对象:

from your_project.app import db

由于默认 conf/your_project.py 中大写配置会自动注入到Flask的config中,因此我们可以在 conf/your_project.py 中对数据库进行详细配置,具体的配置项可参考Flask-SQLAlchemy文档: http://flask-sqlalchemy.pocoo.org/config/

Table to Model

在设计好数据库表之后,通过运行如下命令自动在 your_project.models 模块中生成数据库表对应的model:

$ bash bin/manage table2model

我们可以通过修改 table2model_dest 配置更改model存储的路径。

Model ⟺ dict

我们通过让生成的model继承 BaseModelMixin 注入了两个成员函数:

  • from_dict(dict_obj) : classmethod,将 dict 数据转为model 。

  • to_dict() : method, 将model转变为 dict

Logging

Getting Logger

guniflask将Flask的 app.logger 以及 your_project 的logger 绑定到了gunicorn的 gunicorn.error 上。 因此可以在获取了Flask的 app 对象后使用 app.logger 纪录日志。 也可以在项目模块中按如下方式获取logger:

import logging

log = logging.getLogger(__name__)

log.info('Print log ...')

Log Level

设置日志的级别需要通过添加gunicorn配置项 loglevel ,例如:

loglevel = 'warning'

日志级别包括:

  • debug

  • info

  • warning

  • error

  • critical

gunicorn的配置项如何添加到项目中可参考 Configuration

日志相关的配置项可参考gunicorn文档: http://docs.gunicorn.org/en/stable/settings.html#logging

Debugging Application

Debug Mode

在项目开发过程中,推荐以debug模式启动项目:

$ bash bin/manage debug

在debug模式中会设置如下环境变量:

export GUNIFLASK_DEBUG=1

我们在代码中可以根据是否设置了 GUNIFLASK_DEBUG 环境变量来确定项目是否以debug模式启动。

Debug Settings

以debug模式启动项目时,会强制设定如下gunicorn配置项:

  • accesslog : '-'

  • errorlog : '-'

  • loglevel : 'debug'

  • reload : True

  • reload_extra_files : conf 文件夹下的所有文件

  • workers: 1

  • daemon: False

此时,我们在配置文件中对这些项的设定将不起作用。 特别的,对于reload_extra_files会合并默认配置和自定义的配置。

gunicorn配置项的详情可参考gunicorn文档: http://docs.gunicorn.org/en/stable/settings.html

Auto Reloading

以debug模式启动项目时,如果python模块中或 conf 文件夹中的代码发生了改变,app进程会自动重启并加载最新的代码。

Note

如果我们更改的是gunicorn配置项,则需要手动重启项目才会重新加载最新的gunicorn配置项。

Deploying Application

Active Profiles

如果采用多profile的形式管理配置文件,请确保在启动项目前已正确配置 active_profiles

Starting Application

运行如下命令启动项目:

$ bash bin/manage start

如果提示项目启动失败,可以根据控制台的提示信息以及项目的日志纪录排查出错原因。 项目的错误日志默认存放在项目根目录下 .log 文件夹中。

Stopping Application

运行如下命令停止项目:

$ bash bin/manage stop

项目的pid默认存放在项目根目录下 .pid 文件夹中。

Changelog

0.12.18 (2023-07-01)

  • 限制 pydantic<2

0.12.17 (2023-06-28)

  • 移除对 _request_ctx_stack 的依赖

0.12.16 (2023-02-19)

  • 项目生成的依赖文件Flask-SQLAlchemy的最小版本为3.0.2

  • table2model: 生成的类默认带有 __table_args__ = {'implicit_returning': False} ,避免使用Hologres等部分数据库时commit session报错

0.12.15 (2022-10-23)

  • 限制PyJWT<2.6.0,避免可能出现iat验证错误

0.12.14 (2022-08-01)

  • 限制setproctitle<1.3,修复启动崩溃问题

0.12.13 (2022-07-30)

  • 适配Werkzeug 2.2

0.12.12 (2021-11-19)

  • query参数支持pydantic BaseModel

0.12.11 (2021-11-09)

  • 修复has_role

0.12.10 (2021-09-11)

  • 修复检查RequestBody类型时的异常

0.12.9 (2021-08-12)

  • RequestBody支持 bytes 类型参数

  • 自动生成的配置文件添加 JSON_AS_ASCII = False

  • 移除 ip_address 配置项

0.12.8 (2021-04-30)

  • DataModel 兼容 BaseModelfrom_orm 方法

0.12.7 (2021-04-27)

  • 新增 RequestValidationError 支持用户统一捕获解析请求参数时产生的错误

0.12.6 (2021-04-23)

  • 移除ServiceLock功能

0.12.5 (2021-04-22)

  • 默认使用 GeventScheduler

0.12.4 (2021-04-19)

  • 添加健康检查接口 GET /health

0.12.3 (2021-04-15)

  • 对时间类型的参数的格式化改由pydantic内置的函数实现

0.12.2 (2021-04-09)

  • 修复current_user的递归调用错误

0.12.1 (2021-04-08)

  • 修复stop命令

0.12.0 (2021-04-08)

  • 移除服务发现功能,改由k8s支持

0.11.15 (2021-03-30)

  • 非后台运行状态下,默认日志输出到控制台

0.11.14 (2021-03-24)

  • 修复bean加载过程中可能会访问 @blueprint 中定义的 @property 的问题

0.11.13 (2021-03-12)

  • 添加 head_route 装饰器

0.11.12 (2021-03-04)

  • 修复在未定义 config_key 时Consul拉取应用配置的错误

0.11.11 (2021-03-04)

  • 配置文件支持yaml、json格式

  • 支持从Consul拉取应用配置,同时会覆盖本地已有的配置

  • 移除 app_id 配置项,健康检查接口改为核对应用名称

0.11.10 (2021-02-01)

  • 集成pydantic,DataModel继承pydantic的BaseModel

  • 项目模版生成 __version__ ,用于标识应用版本

0.11.9 (2021-01-25)

  • 修复自动映射数据类型时对None值的处理

0.11.8 (2021-01-22)

  • 修复由build引起的无法识别builtin参数类型的问题

0.11.7 (2021-01-18)

  • 修复setup.py中的依赖信息

0.11.6 (2021-01-18)

  • 修复未指定算法时JwtManager可能无法正常解码token的问题

  • 新增build命令,将项目py文件编译为so文件

0.11.5 (2021-01-11)

  • 自动推断项目名称时支持项目名包含大写字母

  • 修复部分情况下table2model生成的代码缺少引入依赖的问题

  • table2model支持在不加载app的前提下仅依赖于配置文件实现数据模型的生成

  • 新增 app_id 配置项,默认填充为应用指定的唯一标识

  • 新增 ip_address 配置项,默认填充获取的本机IP地址,用于服务注册等功能

0.11.4 (2020-11-18)

  • BaseModelMixin: to_dict 不再默认递归映射relationship,通过 include 参数指定处理哪些relationship

  • table2model: 优化了判断one-to-one关系的方法; 在定义one-to-one和one-to-many关系时用 back_populates 取代 backref

0.11.3 (2020-11-12)

  • 提供以对象形式存储数据的基类 DataModel

  • 去掉生成的py文件中的encoding注释

0.11.2 (2020-11-07)

  • BaseModelMixin: from_dictto_dictupdate_by_dict 支持递归, update_by_dict 暂时不支持更新list形式的字段

  • 修复jwt配置模版中抽取authorization header的bug

0.11.1 (2020-11-05)

  • 支持构建测试应用时自动推断项目的根目录

0.11.0 (2020-11-05)

  • 项目依赖默认不再生成PyMySQL,用户可根据实际使用的数据库选择合适的依赖

  • BaseModelMixin声明query的类型

  • 提供接口级别单元测试方案

  • 移除oauth2相关功能,后续身份认证、授权等相关功能将基于Keycloak实现

  • current_user 的定义移动到 guniflask.security 模块中

  • 内置配置项 project_name 更名为 app_name ,环境变量配置项 GUNIFLASK_PROJECT_NAME 更名为 GUNIFLASK_APP_NAME

0.10.0 (2020-10-19)

  • manage现在可以在任何路径下运行

  • debug模式下会融合对 reload_extra_files 的默认配置和自定义配置

  • gunicorn配置恢复默认使用gevent worker

  • 暂时移除对ASGI的相关支持,包括websocket

  • 修复 from guniflask.config import Settings 的引用错误

0.9.2 (2020-09-17)

  • 新增 guniflask_cli.workers.UvicornWorker 解决uvicorn提供的worker中存在的问题:(1) debug模式下worker无法reload;(2) 父进程退出后worker没有退出

0.9.1 (2020-09-16)

  • 修复未加载gunicorn配置的错误

0.9.0 (2020-09-16)

  • 提供基于类型和默认值为视图函数注入request参数(query、body、file、form、header、cookie)的机制

  • 通过.env文件设置环境变量,移除原有和环境变量配置相关的shell文件

  • 新增 @condition_on_setting ,基于配置项是否存在控制是否初始化实例

  • 移除initdb命令

  • table2model取消了只支持MySQL的限制

  • gunicorn worker默认使用 uvicorn.workers.UvicornWorker

  • 支持websocket

0.8.9 (2020-08-20)

  • 非daemon模式默认不再生成PID文件(修复bug)

0.8.8 (2020-08-18)

  • 移除 GUNIFLASK_ID_STRING

  • 非daemon模式默认不再生成PID文件

0.8.7 (2020-08-11)

  • 修复服务发现功能

0.8.6 (2020-08-10)

  • health endpoint添加了对project name的校验

0.8.5 (2020-08-10)

  • 修复服务注册时找不到app context的问题

  • 移除settings添加内置变量 id_string ,环境变量 GUNIFLASK_ID_STRING 只在服务外部环境中发挥作用

0.8.4 (2020-08-09)

  • stop和restart命令支持设置active profiles,用于处理在profile后缀的gunicorn配置文件中设置了 pidfile 的情况

  • 修复了由自动加载服务发现配置可能导致的循环引用问题

0.8.3 (2020-08-07)

  • settings添加内置变量 id_string ,对应环境变量 GUNIFLASK_ID_STRING

  • health endpoint添加了active profiles的校验,避免程序在错误的profile下启动后无法从Consul中删除服务

0.8.2 (2020-08-04)

  • 多个profile中通过dict作出的配置在读取时应当进行合并,而不是简单替换

0.8.1 (2020-08-04)

  • 添加了服务发现和负载均衡功能,支持通过服务名定位到服务实例

  • MasterLevelLock更名为ServiceLock,通过项目名称和端口号区别实例,解除对gunicorn的依赖

  • 配置guniflask.cors之后自动进行跨域配置

0.8.0 (2020-08-01)

  • guniflask-cli和guniflask的版本同步

  • SQLALCHEMY_TRACK_MODIFICATIONS 的默认配置改由guniflask-cli直接生成到项目代码中

  • 默认添加gunicorn配置项 proc_name 为项目名称,便于查看进程信息

  • 项目配置文件的读取改由guniflask-cli完成

  • 移除@global_singleton,相关功能可以通过MasterLevelLock实现

  • guniflask-manage中的指令合并到guniflask中

  • init命令生成项目时移除了选择应用类型的步骤

  • 默认生成开启跨域的配置

  • 支持将服务注册到Consul