Научит вас создавать службу RESTful API за 10 минут (в середине)

Python

image

1. Введение

предыдущий пост, представляет подробные шаги по созданию RESTful API с использованием Java + Spring Boot + MyBatis; многие мелкие партнеры заявили, что предпочитают писать RESTful API-сервисы на Python, надеюсь, я смогу написать

Эта статья начнется с Python, чтобы представить процесс создания RESTful API, Используемый стек технологий:Flask + flask-restful + flasgger

2. Установите зависимости

Прежде чем писать RESTful API на Python, нам необходимо установить соответствующие зависимости в виртуальной среде, а именно:

  • Flask — базовый веб-фреймворк

  • flask_restful — расширение для Flask, добавляющее поддержку быстрого создания REST API.

  • flasgger — пользовательский интерфейс Swagger, поддерживаемый flask, может генерировать документацию по интерфейсу API.

# 安装flask
pip3 install flask

# 安装flask-restful
pip3 install flask-restful

# 安装flasgger
# 注意:需要更新setuptools
pip3 install -U setuptools
pip3 install flasgger

# 管理数据库的依赖
pip3 install flask_script
pip3 install flask_migrate

3. Hello World

Сначала мы используем Pycharm для создания веб-проекта Flask, код инициализации выглядит следующим образом:

from flask import Flask

app = Flask(__name__)
​

@app.route('/')
def hello_world():
    return 'Hello World!'


if __name__ == '__main__':
    app.run()

Импортируйте классы Api и Resource из файла flask_restful, используйте объект приложения выше, создайте объект API, а затем подготовьте список данных.

from flask_restful import Api,Resource

app = Flask(__name__)

# 实例化一个 Api 对象,用来创建、管理 RESTful Api
api = Api(app)


# 准备一个列表数据
datas = [{'id': 1, 'name': 'xag', 'age': 18}, {'id': 2, 'name': 'xingag', 'age': 19}]

Затем, используя шаблон CBV во Flask, создайте подкласс класса Resource для определения маршрутизации ресурсов.

Возьмите в качестве примера действие GET/POST, перепишите методы get и post и напишите внутреннюю логику для возврата данных.

class UserView(Resource):
    """
    通过继承 Resource 来实现调用 GET/POST 等动作方法
    """
    def get(self):
        """
        GET 请求
        :return:
        """
        return {'code': 200, 'msg': 'success', 'data': datas}


    def post(self):
        # 参数数据
        json_data = request.get_json()

        # 追加数据到列表中
        new_id = len(datas)+1
        datas.append({'id':new_id,**json_data})

        # 返回新增的最后一条数据
        return {'code': 200, 'msg': 'ok', 'success': datas[new_id - 1]}

Наконец, используйте объект экземпляра Api, чтобы полностью раскрыть ресурсы, определенные выше, используя путь

# 暴露接口出去
# 资源路由:UserView
# 路径:/user
api.add_resource(UserView,'/user')

После запуска программы вы можете использовать Postman или cURL для тестирования интерфейса.

image

4. Спроектируйте реальный бой

В реальной разработке проекта структура данных и иерархические отношения часто намного сложнее.Нам нужно один раз интегрировать проект и инкапсулировать его по функциям.Конкретные шаги таковы:

шаг 1,написать файл конфигурации

Создайте новый файл конфигурации config.py, добавьте информацию о подключении к базе данных (в качестве примера возьмем Mysql), включая: имя пользователя, пароль, номер порта, имя базы данных, драйвер подключения и информацию о настройках Swagger.

# config.py
USERNAME = 'root'
PASSWORD = 'root'
HOSTNAME = "127.0.0.1"
PORT = '3306'
DATABASE = 'xag'

DIALECT = 'mysql'
DRIVER = 'pymysql'

# 连接数据的URI
DB_URI = "{}+{}://{}:{}@{}:{}/{}?charset=utf8".format(DIALECT, DRIVER, USERNAME, PASSWORD, HOSTNAME, PORT, DATABASE)

SQLALCHEMY_DATABASE_URI = DB_URI

SQLALCHEMY_TRACK_MODIFICATIONS = True

SWAGGER_TITLE = "API"
SWAGGER_DESC = "API接口"
# 地址,必须带上端口号
SWAGGER_HOST = "localhost:5000"

Шаг 2,База данных сопоставления моделей

Создайте класс модели Foo, который наследует объект SQLAlchemy, используяtablenameУкажите имя сгенерированной таблицы данных, а затем добавьте несколько общих полей

# models.py
from exts import db

class Foo(db.Model):
    """
    模型,将映射到数据库表中
    """
    __tablename__ = 'foo'

    # 主键ID
    id = db.Column(db.INTEGER, primary_key=True, autoincrement=True)
    # 名字
    name = db.Column(db.String(100), nullable=False)
    # 年龄
    age = db.Column(db.INTEGER)

Затем создайте файл manage.py.

Явно импортируйте класс Foo, созданный выше, используйте Migrate в flask_migrate для привязки приложения и базы данных и используйте экземпляр Manager в flask_script для добавления команды скрипта.

# manager.py
from flask_migrate import Migrate, MigrateCommand
from flask_script import Manager

from exts import db
from api_app import app
from models import Foo

manager = Manager(app)
migrate=Migrate(app, db)
manager.add_command('db', MigrateCommand)

if __name__ == '__main__':
    manager.run()

Следует отметить, что модель Foo должна быть импортирована явно, иначе она не может быть сопоставлена ​​с базой данных.

Наконец, сопоставьте модель с базой данных с помощью следующих 3 команд скрипта.

В дополнение к необходимости сгенерировать сценарий миграции в первый раз, чтобы впоследствии сопоставить базу данных, вам нужно выполнить только две последние команды.

# 初始化迁移文件
python3 manager.py db init

# 映射到文件
python3 manager.py db migrate

# 映射到数据库
python3 manager.py db upgrade

Откройте Navicat For Mysql, вы увидите только что сопоставленную таблицу данных и таблицу миграции.

image

Шаг 3,Создание маршрутов ресурсов

Ниже приведен пример создания запроса списка (GET), запроса одной записи (GET), обновления (PUT), добавления (POST) и удаления (DELETE).

Класс marshal_with в flask_restful можно использовать в качестве декоратора для определения функции действия для указания возвращаемых полей, а затем использовать SQLAlchemy ORM для работы с базой данных и прямого возврата данных.

Например: вернуться, чтобы получить список данных

# api_foo.py
from flask_restful import Resource, fields, marshal_with, request

class FooListApi(Resource):
    # 定义要返回的字段
    resource_fields = {
        'id': fields.Integer,
        'name': fields.String,
        'age': fields.String
    }

    # 装饰器,定义返回数据
    @marshal_with(resource_fields)
    def get(self):
        """
        返回所有记录
        :return:
        """
        # 查询数据库
        foos = db.session.query(Foo).all()
        return foos

Для добавления объекта (действие POST)

# api_foo.py
class FooApi(Resource):
    def post(self):
        """
        创建一条记录
        :return:
        """
        # 参数
        params = request.get_json()
        name = params.get("name")
        age = params.get("age")
        # 构建一个模型
        foo = Foo(name=name, age=age)

        # 加入到数据库
        db.session.add(foo)
        db.session.commit()

        return success("新增一条记录成功!")

Шаг 4,Объединение возвращаемых данных

Чтобы гарантировать согласованность возвращаемой структуры данных, код возврата, возвращаемая информация и данные могут быть инкапсулированы один раз, отформатированы и возвращены через jsonify.

# restful_utils.py
from flask import jsonify

class HttpCode(object):
    ok = 200
    un_auth_error = 401
    params_error = 400
    server_error = 500

def restful_result(code, message, data):
    return jsonify({"code": code, "message": message, "data": data or {}})

def success(message="", data=None):
    """
    正确返回
    :return:
    """
    return restful_result(code=HttpCode.ok, message=message, data=data)

Шаг 5,открытый интерфейс

Используйте объект экземпляра Api в flask_restful, чтобы раскрыть маршрутизацию ресурсов, определенную выше.

#api_app.py
from flask_restful import Api

api = Api(app)

# 某一条记录
api.add_resource(FooApi, '/api/v1/foo','/api/v1/foo/<int:id>')

# 所有记录
api.add_resource(FooListApi, '/api/v1/foos')

Шаг 6,Автоматически генерировать интерфейсные документы

Flask также может использовать Swagger для автоматического создания справочных документов по интерфейсу.

Сначала прочитайте конфигурацию из файла конфигурации config.py и создайте экземпляр объекта Swagger.

#api_app.py
from flasgger import Swagger

# API可视化管理
swagger_config = Swagger.DEFAULT_CONFIG

# 标题
swagger_config['title'] = config.SWAGGER_TITLE   
# 描述信息
swagger_config['description'] = config.SWAGGER_DESC
# Host    
swagger_config['host'] = config.SWAGGER_HOST    

# 实例化
swagger = Swagger(app,config=swagger_config)

Затем добавьте содержимое аннотации swagger в действие маршрутизации ресурсов, включая: метод запроса, параметры, данные ответа, информацию описания и т. д.

Для получения подробной информации см.:editor.swagger.io/#/

В качестве примера возьмем получение определенного фрагмента данных:

class FooApi(Resource):

    resource_fields = {
        'id': fields.Integer,
        'name': fields.String,
        'age': fields.String
    }

    @marshal_with(resource_fields)
    def get(self, id):
        """获取用户信息
    ---
    schemes:
      - http
    parameters:
      - name: id
        in: path
        type: integer
        required: true
        default: 1
        description: 用户id

    responses:
      200:
        description: 返回用户信息
        examples:
                {
                    "id": 1,
                    "name": "xag",
                    "age":"18"
                }
    """
        foo = db.session.query(Foo).get(id)
        return foo

Наконец, запустите проект, перейдите по ссылке ниже, вы можете увидеть определенную службу API RESTful.

http://localhost:5000/apidocs/#/

image

5. Наконец

Выше приведен полный процесс реализации RESTful API через одну таблицу Flask + flask_restful.Для нескольких таблиц, участвующих в проекте, вам нужно только изменить логическую операцию базы данных.

Я загрузил весь исходный код в статье на фоне официального аккаунта, следите за официальным аккаунтом " AirPython", а затем ответ"rest2», чтобы получить весь исходный код

Если вы считаете, что статья хорошая, ставьте лайк и делитесь. Ваше утверждение - моя самая большая поддержка и поддержка.

Рекомендуемое чтение Научу вас создавать службу RESTful API за 10 минут (часть 1)

Порекомендуйте несколько высококачественных рыболовных плагинов Chrome, которые помогут вам отправиться на воду.

Каков опыт использования Python для анализа записей группового чата WeChat?