使用cookiecutter-flask快速生成python后端项目

Write code that writes code. Code generators increase your productivity and help avoid duplication.


天下武功,唯快不破

每当我们启动一个新项目的时候,总有很多重复性工作,创建后端app模板就是其中之一。如果是使用django还好,django提供了生成项目app的命令直接创建,不过貌似现在很多pythoner都倾向于用flask这种微框架。虽然很多成功的项目是基于django(Instagram,Disqus,Pinterest等)构建,不过笔者还是更喜欢flask这种微框架。flask的好处在于你可以随意替换插件(ORM,模板等),相比django更加灵活。缺点就是有时候会选择困难,不知道如何组织大型项目,而且需要学习各种flask的插件,实际上把flask一套插件都整明白也需要一定的学习成本。今天笔者介绍的这个Cookiecutter项目就是专门用来解决项目模板生成问题的,经过了python3.5.2生产环境的检验。


使用cookiecutter-flask生成模板

使用很简单(需要具备基本的flask框架知识),cookiecutter-flask项目地址:

$ pip install cookiecutter
$ cookiecutter https://github.com/sloria/cookiecutter-flask.git

执行完以后按照提示填写app名称(注意app名称符合python包名规范)就可以生成了,非常方便。后边注意了,有新手在github的issue里提出没有一个新手指引,实际上生成到README里了。

===============================
flaskapp
===============================

Test flask-cookiecutter


Quickstart
----------

First, set your app's secret key as an environment variable. For example,
add the following to ``.bashrc`` or ``.bash_profile``.

.. code-block:: bash

    export APP_SECRET='something-really-secret'

Before running shell commands, set the ``FLASK_APP`` and ``FLASK_DEBUG``
environment variables ::

    export FLASK_APP=/path/to/autoapp.py
    export FLASK_DEBUG=1

Then run the following commands to bootstrap your environment ::

    git clone https://github.com/PegasusWang/app
    cd app
    pip install -r requirements/dev.txt
    bower install
    flask run

You will see a pretty welcome screen.

Once you have installed your DBMS, run the following to create your app's
database tables and perform the initial migration ::

    flask db init
    flask db migrate
    flask db upgrade
    flask run


Deployment
----------

In your production environment, make sure the ``FLASK_DEBUG`` environment
variable is unset or is set to ``0``, so that ``ProdConfig`` is used.


Shell
-----

To open the interactive shell, run ::

    flask shell

By default, you will have access to the flask ``app``.


Running Tests
-------------

To run all tests, run ::

    flask test


Migrations
----------

Whenever a database migration needs to be made. Run the following commands ::

    flask db migrate

This will generate a new migration script. Then run ::

    flask db upgrade

To apply the migration.

For a full migration command reference, run ``flask db --help``.

按照步骤执行一次就能看到效果了。你只需要新建自己的蓝图,开始填写自己的业务就行了。


添加flask_restful, redis,sentry,flask_admin等支持

项目自动生成的模板里头已经引入了很多插件了,不过还有几个比较常用的插件,比如redis支持,sentry支持(sentry记录异常信息非常好用),flask_admin(类似django的后台管理)等。最后笔者的extensions.py如下:

# -*- coding: utf-8 -*-
"""Extensions module. Each extension is initialized in the app factory located
in app.py."""

import os
import types

from flask_admin import Admin
from flask_admin.contrib.sqla import ModelView
from flask_babel import Babel
from flask_bcrypt import Bcrypt
from flask_caching import Cache
from flask_debugtoolbar import DebugToolbarExtension
from flask_login import LoginManager
from flask_mail import Mail
from flask_migrate import Migrate
from flask_redis import FlaskRedis
from flask_restful import Api
from flask_sqlalchemy import SQLAlchemy
from flask_wtf.csrf import CsrfProtect
from mockredis import MockRedis
from raven.contrib.flask import Sentry


bcrypt = Bcrypt()
csrf_protect = CsrfProtect()
login_manager = LoginManager()
db = SQLAlchemy()
migrate = Migrate()
cache = Cache()
debug_toolbar = DebugToolbarExtension()
api = Api(decorators=[csrf_protect.exempt])
mail = Mail()
babel = Babel()    # 用babel处理时区转换问题
admin = Admin()
sentry = Sentry()    # settings里配置Setnry服务器地址


def api_route(self, *args, **kwargs):
    """ 给flask api加上route功能,避免直接调用api.add_resource函数了.
    具体请参考crm_backend.employee.api里的使用
    http://flask.pocoo.org/snippets/129/
    """
    def wrapper(cls):
        self.add_resource(cls, *args, **kwargs)
        return cls
    return wrapper


api.route = types.MethodType(api_route, api)


class MockRedisWrapper(MockRedis):
    """A wrapper to add the `from_url` classmethod
    https://github.com/underyx/flask-redis
    """
    @classmethod
    def from_url(cls, *args, **kwargs):
        return cls(decode_responses=True)


if os.environ.get('USE_CONFIG') == 'prod':
    redis_store = FlaskRedis(decode_responses=True)
else:
    redis_store = FlaskRedis.from_custom_provider(MockRedisWrapper)

当然也可以按照你自己的需求自己增删功能,最近的flask版本在DEBUG模式下支持自动检测重启,开发起来还是非常爽快的,笔者最近的几个后端项目都是用cookiecutter-flask生成后自己按需修改,感兴趣的可以试试。

Ref

cookiecutter-flask

cookiecutter