简体   繁体   English

Flask-Restx Api.model(strict=True) 允许未指定的参数

[英]Flask-Restx Api.model(strict=True) allowing unspecified params

I have a simple Users resource with a put method to update all user information except user password.我有一个简单的用户资源,它带有一个 put 方法来更新除用户密码之外的所有用户信息。 According to Flask-Restx docs when a model has set the strict and validation params to true, a validation error will be thrown if an unspecified param is provided in the request.根据 Flask-Restx 文档,当 model 将严格和验证参数设置为 true 时,如果在请求中提供了未指定的参数,则会引发验证错误。 However, this doesn't seem to be working for me.但是,这似乎对我不起作用。

Model definition: Model定义:

from flask_restx import Namespace, Resource, fields, marshal

users_ns = Namespace("users")

user = users_ns.model(
    "user",
    {
        "user_name": fields.String(example="some_user", required=True),
        "email": fields.String(example="some.user@email", required=True),
        "is_admin": fields.Boolean(example="False"),
        "is_deactivated": fields.Boolean(example="False"),
        "created_date": fields.DateTime(example="2020-12-01T01:59:39.297904"),
        "last_modified_date": fields.DateTime(example="2020-12-01T01:59:39.297904"),
        "uri": fields.Url("api.user"),
    },
    strict=True,
)

user_post = users_ns.inherit(
    "user_post", user, {"password": fields.String(required=True)}
) # Used for when 

Resource and method definition:资源和方法定义:

from api.models import Users

class User(Resource):
    @users_ns.marshal_with(user)
    @users_ns.expect(user, validate=True)
    def put(self, id):
        """
        Update a specified user.
        """

        user = Users.query.get_or_404(id)
        body = request.get_json()

        user.update(body)

        return user

Failing Test:失败的测试:

def test_update_user_invalid_password_param(self, client, db):
        """ User endpoint should return 400 when user attempts to pass password param to update. """
        data = {
            "user_name": "some_user",
            "email": "some.user@email.com",
            "password": "newpassword",
        }

        response = client.put(url_for("api.user", id=1), json=data)

        assert response.status_code == 400

The response.status_code here is 200 because no validation error is thrown for the unspecified param passed in the body of the request.此处的 response.status_code 为 200,因为在请求正文中传递的未指定参数不会引发验证错误。

Am I using the strict param improperly?我是否不正确地使用了严格的参数? Am I misunderstanding the behavior of strict?我是否误解了严格的行为?

UPDATED: I've added the test for strict model param from Flask-RestX repo (can be found here ) for more context on expected behavior:更新:我添加了对来自 Flask-RestX 存储库的严格 model 参数的测试(可以在此处找到)以获取有关预期行为的更多上下文:

def test_api_payload_strict_verification(self, app, client):
        api = restx.Api(app, validate=True)
        ns = restx.Namespace("apples")
        api.add_namespace(ns)

        fields = ns.model(
            "Person",
            {
                "name": restx.fields.String(required=True),
                "age": restx.fields.Integer,
                "birthdate": restx.fields.DateTime,
            },
            strict=True,
        )

        @ns.route("/validation/")
        class Payload(restx.Resource):
            payload = None

            @ns.expect(fields)
            def post(self):
                Payload.payload = ns.payload
                return {}

        data = {
            "name": "John Doe",
            "agge": 15,  # typo
        }

        resp = client.post_json("/apples/validation/", data, status=400)
        assert re.match("Additional properties are not allowed \(u*'agge' was unexpected\)", resp["errors"][""])

I resolved my issue by pulling the latest version of Flask-RESTX from Github.我通过从 Github 中提取最新版本的 Flask-RESTX 解决了我的问题。 The strict parameter for models was merged after Flask-RESTX version 0.2.0 was released on Pypi in March of 2020 (see the closed issue in Flask-RESTX repo for more context).在 2020 年 3 月在 Pypi 上发布 Flask-RESTX 版本 0.2.0 后,模型的严格参数被合并(有关更多上下文,请参阅 Flask-RESTX 存储库中的已关闭问题)。 My confusion arose because the documentation appears to represent the latest state of master and not the last Pypi release.我的困惑出现了,因为文档似乎代表了最新的 state,而不是最新的 Pypi 版本。

It's been a while since I touched on this but from what I can tell, I don't think you are using the strict param correctly.自从我谈到这个已经有一段时间了,但据我所知,我认为你没有正确使用严格的参数。 From the documentation here , the :param bool strict is defined as这里的文档中, :param bool strict定义为

:param bool strict: validation should raise an error when there is param not provided in schema :param bool strict: 当模式中没有提供参数时,验证应该引发错误

But in your last snippet of code, you are trying to validate with the dictionary data with the body of the request.但是在您的最后一段代码中,您正尝试使用带有请求正文的字典data进行验证。

If I recall well again, for this sort of task you need to use (and as you mentioned) a RequestParser .如果我再次记得,对于这类任务,您需要使用(并且正如您所提到的) RequestParser There's a good example of it here - flask - something more strict than @api.expect for input data?这里有一个很好的例子——flask——比@api.expect 输入数据更严格?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM