@Dogrtt
Qt/Python разработчик

Как избежать дублирования кода в проекте с использованием Flask-RESTplus + Marsmallow?

Начинаю потихоньку разбираться, как реализовывать REST API на Flask с помощью Flask-RESTplus. Сейчас просматриваю статьи и видео, в которых авторы используют в дополнение к Flask-RESTplus де/сериализатор Marshmallow. Один из первых же вопросов который стал передо мной это действительно ли необходимо дублировать код описания моделей?
Сейчас поясню, вот у нас есть описание моделей (де-факто описание таблиц в бд и их связей) SQLAlchemy, но это, как я понимаю, никак нам не поможет, ведь модели полученные через api.model() для использования в @api.expect() (может еще где, я пока не знаю), это больше сродни описанию форм из модуля Flask-WTF, так? Но если мы хотим использовать еще и Marshmallow в прикуску, то придется реализовывать дублирующее описание через Schema. Вот пример:
spoiler
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from flask_restplus import Resource, fields
from marshmallow import Schema, post_load, fields as ma_fields

from application import api


class MyModel(object):
    def __init__(self, egg, spam):
        self.egg = egg
        self.spam = spam
    
    def __repr__(self):
        return 'Egg -> {} ; Spam -> {}'.format(self.egg, self.spam)


class MyModelSchema(Schema):
    egg = ma_fields.String()
    spam = ma_fields.String()
    
    @post_load
    def create_mymodel(self, data):
        return MyModel(**data)


my_model = api.model('MyModel', {
    'egg': fields.String('Put egg here'), 
    'spam': fields.String('Put spam here')})

fs = []
f1 = MyModel('egg1', 'spam1')
fs.append(f1)


@api.route('/hello')
class MyResource(Resource):
    def get(self):
        schema = MyModelSchema(many=True)
        return schema.dump(fs)
    
    @api.expect(my_model)
    def post(self):
        schema = MyModelSchema()
        a = schema.load(api.payload)
        fs.append(a.data)
        return {'ok': 'all is fine'}, 201



И еще вопрос, существует модуль flask-marshmallow, может лучше использовать его?
  • Вопрос задан
  • 446 просмотров
Пригласить эксперта
Ответы на вопрос 2
xSkyFoXx
@xSkyFoXx
В продолжение к комментариям:

Мне кажется вы переусложняете приложение.

На начальном этапе разработки вы можете абстрагироваться от авторизации и мыслть в терминологии дизайна и кодинга API. Ваши API методы будут "обогощать" результат выборки из базы данных, для которого вы можете написать себе ровно один небольшой хелпер, который будет пребразовывать ответ из БД в словарь и затем возвращать этот словарь, обёрнутый в jsonify.

Следующий шаг - это Token-Based Authentication. Для неё вы пределываете отдельные ручки, которые выдают или не выдают вашему клиенту токен. В идеале - требуемая модификация вашего основного API - это декоратор авторизации к классу или функциям.

Документация - отдельный вопрос. Я противник свагера, так как с ним мой Python код начинает походить на код на JavaScript.
Ответ написан
Комментировать
@domanskiy
Очень помогло использование метода SQLAlchemyAutoSchema в последней версии flask-marshmallow
Сам генерирует схему )

class DieCutSchema(ma.SQLAlchemyAutoSchema):
    class Meta:
        model = DieCut


@api.route('/diecuts')
def index():
    items = DieCut.query.all()
    items_schema = DieCutSchema(many=True)
    result = items_schema.dump(items)
    return jsonify(result)
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы