问题
With Flask 1.1.2, marshmallow 3.6.1 and webargs 6.1.0 all of my arguments are always missing
.
Schema:
class ExportSearchSchema(Schema):
limit = fields.Integer(required=False, allow_none=False, default=10, missing=10)
offset = fields.Integer(required=False, allow_none=False, default=0, missing=0)
status = fields.Str(required=False)
class Meta:
unknown = RAISE
@validates('status')
def validate_status(self, value):
if value and value not in ['complete', 'pending', 'failed']:
raise ValidationError('Invalid status: {}'.format(value))
@validates('limit')
def validate_limit(self, value):
if value > 100:
raise ValidationError('Max limit is 100')
if value < 1:
raise ValidationError('Limit must be a positive number and less than 100')
@validates('offset')
def validate_offset(self, value):
if value < 0:
raise ValidationError('Offset must be equal to, or greater than 0')
blueprint.py:
from flask import jsonify, Response
from flask import Blueprint
from marshmallow import Schema, fields, validates, ValidationError, RAISE
from webargs.flaskparser import use_args
exports = Blueprint('exports', __name__)
@exports.route('exports/',
methods=['GET'], strict_slashes=False)
@use_args(ExportSearchSchema(unknown=RAISE))
def get_export_list(qparams):
log.info("qparams {}".format(qparams)
response = jsonify({'data': 'export_list'})
response.mimetype = 'application/json'
return response
When I curl any value for limit
or offset
it always uses the default
value.
curl http://localhost:8000/exports?limit=5930
log: "qparams {'limit': 10, 'offset': 0}"}
I expect a ValidationError
to be raised because the limit should be > 100.
When I curl an unknown parameter I expect a ValidationError
to be raised because it's an unknown parameter. This also does not work as expected.
curl http://localhost:8000/exports?lkfjdskl=fkjdsl
returns a 200 and has no qparams
.
What am I doing wrong here in combining webargs
, Flask
, and marshmallow
?
回答1:
The logic changed in webargs 6.
Before webargs 6, the parser would iterate over the fields of the schema and, by default, search over multiple locations to find the value.
In webargs 6, the parser just passes the data from a single location to the schema. The location defaults to "json"
.
Since you're using query arguments, you need to specify it explicitly:
@use_args(ExportSearchSchema(unknown=RAISE), location="query")
Since you don't specify the location, json body is assumed, nothing is found, and the default values are used.
This is documented in webargs docs: "upgrading to 6.0".
来源:https://stackoverflow.com/questions/62480777/flask-marshmallow-3-and-webargs-use-args-fails-to-parse-arguments