[英]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.