flask - что-то более строгое, чем @api.expect для входных данных?

В моем API flask-restplus я хотел бы не только проверять эти входные данные, как в следующем примере.

resource_fields = api.model('Resource', {
    'name': fields.String(default = 'string: name', required = True),
    'state': fields.String(default = 'string: state'),
})

@api.route('/my-resource/<id>')
class MyResource(Resource):
    @api.expect(resource_fields, validate=True)
    def post(self):
        ...

должно иметь поле «имя» и может иметь поле «состояние», а также проверять, что нет других полей (и вызывать ошибку, если это произойдет). Есть ли другой декоратор для этого? Могу ли я проверить правильность введенных данных пользовательской функцией?


person user1403546    schedule 19.12.2016    source источник


Ответы (3)


Вместо использования словаря для своих полей попробуйте использовать RequestParser (flask-restplus принимает как задокументированные здесь. Таким образом, вы можете вызвать parser.parse_args(strict=True), который вызовет исключение 400 Bad Request, если во входных данных присутствуют какие-либо неизвестные поля.

my_resource_parser = api.parser()
my_resource_parser.add_argument('name', type=str, default='string: name', required=True)
my_resource_parser.add_argument('state', type=str, default='string: state')

@api.route('/my-resource/<id>')
class MyResource(Resource):
    def post(self):
        args = my_resource_parser.parse_args(strict=True)
        ...

Дополнительные инструкции по использованию request_parser с вашим ресурсом см. в пример приложения ToDo в репозитории flask-restplus.

person shiv    schedule 20.12.2016
comment
Кажется, полезная нагрузка не документируется в Swagger, когда вы создаете ее таким образом... или я делаю что-то не так? Как бы вы использовали синтаксический анализатор, как указано выше, но при этом сохранили бы описание/примеры полезной нагрузки? - person Alexis.Rolland; 04.08.2018
comment
Хорошо, я нашел ответ в документации здесь: flask-restplus.readthedocs.io/en/stable/ - person Alexis.Rolland; 04.08.2018
comment
проблема заключается в том, что использование RequestParser будет УСТАРЕВШИМ. flask-restplus.readthedocs.io/en/stable/parsing.html - person andilabs; 01.06.2020

Вот еще один ответ, чтобы завершить ответ от @shiv. Следующий фрагмент кода позволяет задокументировать вашу полезную нагрузку в документе Swagger, сгенерированном Flask Restplus. Взято из документации по декоратору ожидания:

my_resource_parser = api.parser()
my_resource_parser.add_argument('name', type=str, default='string: name', required=True)
my_resource_parser.add_argument('state', type=str, default='string: state')

@api.route('/my-resource/<id>', endpoint='with-parser')
class MyResource(Resource):
    @api.expect(my_resource_parser)
    def post(self):
        args = my_resource_parser.parse_args(strict=True)
        ...
person Alexis.Rolland    schedule 04.08.2018

Для тех, кто хочет продолжать использовать api.model, а не синтаксический анализатор запросов, можно выполнить итерацию по входным данным (предполагаемый список) по сравнению с моделью. Модель ведет себя как словарь.

from flask_restplus import abort

def check_exact(response_list, model):
    for response_dict in response_list:
        for key in response_dict:
            if key not in model:
                abort(400, "Non-specified fields added", field=key)

...

@ns.expect(my_model, validate=True)
def post(self, token):
    """Add new set of responses
    """
    check_exact(api.payload['responses'], my_model)
    ...
person Nick Jenkins    schedule 10.12.2018
comment
зачем идти по этому маршруту, можно легко добавить validate=True для проверки - person Aqib; 27.05.2019
comment
Проверка не дает сбоев при неожиданных дополнительных ключах, что и привело меня на эту страницу. Это стало некоторым сюрпризом. - person flayman; 02.09.2019