Python Flask API - 入门套件和项目布局

514 阅读4分钟

Python Flask API - 入门套件和项目布局

API改变了我们构建应用程序的方式,世界上有无数个API的例子,也有许多方法来结构或设置你的API。今天我们将讨论我如何使用Python和Flask来构建和记录REST API,以满足各种需求。

像往常一样,我提供了示例应用程序,对于这种情况,是供大家使用和建立的入门套件。

在我们开始写代码之前...

让我们先讨论一下项目的依赖性,为什么每一个都是必要的,以及它如何能使我们的项目受益。

  • [flasgger]: 这是一个帮助我们将swagger文档集成到flask API中的模块。
  • [flask-marshmallow]:对象序列化器,是解析和转储JSON数据进出我们API的理想选择。
  • [apispec]:marshmallow和flasgger之间的整合需要。

项目布局

我们将开始讨论项目的布局,看看文件夹结构是怎样的。

project/
    api/
        model/
            __init__.py
            welcome.py
        route/
            home.py
        schema/
            __init__.py
            welcome.py

    test/
        route/
            __init__.py
            test_home.py
        __init.py

    .gitignore
    app.py
    Pipfile
    Pipfile.lock

我认为文件夹结构是不言自明的,但让我们逐个看一下 API 模块。

API模块将承载我们的应用程序代码,从模型、路由、模式和控制器(如果需要的话)(尽管我通常不创建这些)。

  • models 是我们应用程序的数据描述符,在许多情况下与数据库模型有关,例如在使用sqlalchemy ,尽管它们可以是任何表示我们数据结构的类。
  • routes 是我们应用程序的路径(例如/api/home或/api/users),它是我们将定义路由逻辑、数据检索、插入、更新等的地方。
  • schemas 是我们数据结构的视图(序列化器)。我们应该在每个模型中至少有一个模式。模式将有它自己的定义,我们将在后面看到。

路线示例

home.py

from http import HTTPStatus
from flask import Blueprint
from flasgger import swag_from
from api.model.welcome import WelcomeModel
from api.schema.welcome import WelcomeSchema

home_api = Blueprint('api', __name__)


@home_api.route('/')
@swag_from({
    'responses': {
        HTTPStatus.OK.value: {
            'description': 'Welcome to the Flask Starter Kit',
            'schema': WelcomeSchema
        }
    }
})
def welcome():
    """
    1 liner about the route
    A more detailed description of the endpoint
    ---
    """
    result = WelcomeModel()
    return WelcomeSchema().dump(result), 200

这是一个路由的最基本定义的例子,让我们逐行看一下。

home_api = Blueprint('api', __name__)

蓝图的创建,我喜欢把应用程序分成不同的蓝图,我在文件的开头提供了父路由,在这个例子中是/api ,所有后续的路由都是相对于这个的。

@home_api.route('/')
@swag_from({
    'responses': {
        HTTPStatus.OK.value: {
            'description': 'Welcome to the Flask Starter Kit',
            'schema': WelcomeSchema
        }
    }
})
def welcome():
    """
    1 liner about the route
    A more detailed description of the endpoint
    ---
    """
    result = WelcomeModel()
    return WelcomeSchema().dump(result), 200

接下来是路由本身,在这种情况下,我们首先为应用程序定义路由,有几种方法可以做到这一点。在定义完路由后,我们需要为swagger文档提供信息。我设置了一个例子,我们把响应对象和端点描述定义为字符串字面。

然后我们需要为我们的应用程序放置代码,以最终从API返回一个对象。为了将对象序列化,我们使用我们的模式,正如在代码中可以看到的那样。

模式

模式是这个设置的一个非常重要的部分,在flask-marshmallow文档中对其进行了详细的介绍,但本质上模式是一个类,它定义了模型和其他模型之间的属性和关系,以便python能够序列化这些对象。

下面是我的区块链代码中的一些示例模式。

from flask_marshmallow import Schema
from marshmallow.fields import Nested, Str, Number
from api.schema.transaction import TransactionSchema


class BlockSchema(Schema):
    class Meta:
        # Fields to expose
        fields = ["index", "timestamp", "transactions", "nonce", "previous_hash", "hash"]

    index = Number()
    nonce = Str()
    timestamp = Number()
    previous_hash = Str()
    hash = Str()
    transactions = Nested(TransactionSchema, many=True)
from flask_marshmallow import Schema
from marshmallow.fields import Nested
from api.schema.block import BlockSchema


class BlockchainSchema(Schema):
    class Meta:
        # Fields to expose
        fields = ["blockchain"]

    blockchain = Nested(BlockSchema, many=True)

测试

与其他应用程序一样,测试是超级重要的,我可以写一整篇文章来讨论为什么。但在这里我们将保持简单。对于测试,我只是简单地使用了python的unittest模块,并且我试图为每个组件建立测试。下面是一个关于我们的主页路线的例子。

from unittest import TestCase
from app import create_app


class TestWelcome(TestCase):
    def setUp(self):
        self.app = create_app().test_client()

    def test_welcome(self):
        """
        Tests the route screen message
        """
        rv = self.app.get('/api/')

        # If we recalculate the hash on the block we should get the same result as we have stored
        self.assertEqual({"message": 'Hello World!'}, rv.get_json())

应用程序

最后,我们需要一个地方,把所有的东西粘在一起,我们创建我们的python API

from flask import Flask
from flasgger import Swagger
from api.route.home import home_api

def create_app():
    app = Flask(__name__)

    app.config['SWAGGER'] = {
        'title': 'Flask API Starter Kit',
    }
    swagger = Swagger(app)

    app.register_blueprint(home_api, url_prefix='/api')

    return app


if __name__ == '__main__':
    from argparse import ArgumentParser

    parser = ArgumentParser()
    parser.add_argument('-p', '--port', default=5000, type=int, help='port to listen on')
    args = parser.parse_args()
    port = args.port

    app = create_app()

    app.run(host='0.0.0.0', port=port)

在app.py文件中,我们定义了python flask应用程序。在create_app 函数中,你需要为swagger配置指定你的应用名称,你的每一个蓝图,任何其他的初始化步骤,如数据库连接,都会在这里发生,在flask快速入门中也有很好的例子。

环境设置

  • 查看flask-api-starter-kit中的代码

  • 安装需求pipenv install

  • 用来启动服务器。pipenv run python -m flask run

  • 运行测试。pipenv run python -m unittest image.png

Swagger文档用户界面示例


我希望这个教程和项目能帮助你建立你的下一个API。