question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Webargs 6.0.0 has broken Flaskparser @use_kwargs: Never parses query string or formdata

See original GitHub issue

Hello,

Your recent release of 6.0.0 of webargs has unexpectedly broken our Flask apps. It seems now the @use_kwargs decorator from the webargs.flaskparser completely fails to parse GET query string parameters or POST form-data parameters. Only JSON request bodies ever get parsed anymore.

Here is an example Flask app that shows the problem:

from flask import Flask, jsonify
from webargs import fields
from webargs.flaskparser import use_kwargs

app = Flask(__name__)

@app.route("/test1", methods=["GET", "POST", "PUT"])
@use_kwargs({
    "page": fields.Int(missing=1),
    "per_page": fields.Int(missing=20),
    "full": fields.Bool(missing=False),
})
def test1(**kwargs):
    return jsonify(kwargs)

@app.route("/test2", methods=["GET", "POST", "PUT"])
@use_kwargs({
    "name": fields.Str(required=True),
})
def test2(**kwargs):
    return jsonify(kwargs)

app.run()

The endpoint “/test1” has three optional parameters each with default values when missing. If I make a GET request (with query parameters) or a POST request with application/x-www-form-urlencoded format, webargs completely fails to pick up my parameters and only sees the defaults.

In the endpoint “/test2” I have a required parameter, which again fails to parse on GET or form-data post but works on JSON post only. Here are some curl examples:

# GET request doesn't parse any param
% curl 'http://localhost:5000/test1?page=5&per_page=2&full=1'
{"full":false,"page":1,"per_page":20}

# Normal POST doesn't parse any param
% curl -X POST -d page=5 -d per_page=2 -d full=1 'http://localhost:5000/test1'
{"full":false,"page":1,"per_page":20}

# JSON POST actually does parse params
% curl -X POST -H 'Content-Type: application/json' -d '{"page": 5, "per_page": 2, "full": true}' 'http://localhost:5000/test1'
{"full":true,"page":5,"per_page":2}

# GET is "missing required parameter"
% curl 'http://localhost:5000/test2?name=alice'
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>422 Unprocessable Entity</title>
<h1>Unprocessable Entity</h1>
<p>The request was well-formed but was unable to be followed due to semantic errors.</p>

# POST is "missing required parameter"
% curl -X POST -d name=alice 'http://localhost:5000/test2'
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>422 Unprocessable Entity</title>
<h1>Unprocessable Entity</h1>
<p>The request was well-formed but was unable to be followed due to semantic errors.</p>

# POST JSON actually works
% curl -X POST -H 'Content-Type: application/json' -d '{"name": "alice"}' 'http://localhost:5000/test2'
{"name":"alice"}

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:3
  • Comments:17 (9 by maintainers)

github_iconTop GitHub Comments

2reactions
reinhard-muellercommented, Mar 31, 2020

The reason why I would like to support both query params and form params is that I have views which support being called with GET (using query params) or POST (using form params).

BTW @kirsle you could also set parser.location="json_or_form" to change the default for all use_kwargs calls that don’t explicity set a location.

2reactions
lafrechcommented, Feb 29, 2020

@kirsle

You can do

@use_args(..., location="query"')
@use_args(..., location="json_or_form")
def view_func(...):

@captainkw, good catch. We’ll fix the README example.

Indeed this change impacts code relying on a single call to use_args to pass both body and query params. Those codes will need to be adapted. I don’t think it makes the use case impossible to achieve. It just takes an adaptation. Verbose in huge code base, but feasible.

Meanwhile, the app can still use webargs 5.

This changes makes webargs code clearer and more maintainable, and most importantly, it allows the Schema features (pre/post load decorators, unknown fields management) to be used, which was an issue and a source of questions for a lot of users.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Advanced Usage - webargs 8.2.0 documentation
For example, here is a custom Flask parser that handles nested query string arguments. import re from webargs import core from webargs.flaskparser ......
Read more >
webargs - Read the Docs
is a custom Flask parser that handles nested query string arguments. import re from webargs import core from webargs.flaskparser import ...
Read more >
webargs(1) - Arch manual pages
For example, here is a custom Flask parser that handles nested query string arguments. import re from webargs import core from webargs.flaskparser import ......
Read more >
Flask, Marshmallow 3, and webargs use_args fails to parse ...
The logic changed in webargs 6. Before webargs 6, the parser would iterate over the fields of the schema and, by default, ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found