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.

Parsing arguments always returns None

See original GitHub issue

parsing the arguments always returns None, even if trying the most basic syntax taken from the quick start page. Maybe I have a typo I failed to see.

Versions: Flask: 1.1.2 Marshmallow: 3.6.0 Flask-marshmallow: 0.12 webargs: 6.1.0

Code:

from pprint import pprint

from flask import request
from flask_restful import Resource
from webargs import fields, validate
from webargs.flaskparser import parser

# Flask-restful resource, GET method called with ?type=99999
class WebsiteList(Resource):
    @classmethod
    # @use_kwargs(website_args)
    def get(cls):
        website_args = {
            'type': fields.String(
                required=True,
                validate=validate.Range(min=0, max=6, error="testing error, never triggered")
            ),
        }

        # Line below outputs: ImmutableMultiDict([('type', '6')])
        pprint(request.args)

        args = parser.parse(website_args, request)
        # Line below outputs: None
        pprint(args)

I have also tried the decorator @use_kwargs(website_args) (And define website_args beforehand of course), but I get a traceback for TypeError: ‘NoneType’ object is not iterable:

Traceback (most recent call last):
  File "C:\Users\Marco\.virtualenvs\api-kHflOUBu\lib\site-packages\flask\app.py", line 1950, in full_dispatch_request
    rv = self.dispatch_request()
  File "C:\Users\Marco\.virtualenvs\api-kHflOUBu\lib\site-packages\flask\app.py", line 1936, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "C:\Users\Marco\.virtualenvs\api-kHflOUBu\lib\site-packages\flask_restful\__init__.py", line 468, in wrapper
    resp = resource(*args, **kwargs)
  File "C:\Users\Marco\.virtualenvs\api-kHflOUBu\lib\site-packages\flask\views.py", line 89, in view
    return self.dispatch_request(*args, **kwargs)
  File "C:\Users\Marco\.virtualenvs\api-kHflOUBu\lib\site-packages\flask_restful\__init__.py", line 583, in dispatch_request
    resp = meth(*args, **kwargs)
  File "C:\Users\Marco\.virtualenvs\api-kHflOUBu\lib\site-packages\webargs\core.py", line 364, in wrapper
    args, kwargs, parsed_args, as_kwargs
  File "C:\Users\Marco\.virtualenvs\api-kHflOUBu\lib\site-packages\webargs\core.py", line 298, in _update_args_kwargs
    kwargs.update(parsed_args)
TypeError: 'NoneType' object is not iterable

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:6 (2 by maintainers)

github_iconTop GitHub Comments

1reaction
sirosencommented, Jun 10, 2020

I just confirmed that this is not an incompatibility between webargs and flask-restful.

the following example, nearly identical to the OP's, produces a 422 error
from flask import request, Flask
from flask_restful import Resource, Api
from webargs import fields
from webargs.flaskparser import parser

app = Flask(__name__)
api = Api(app)


class Test(Resource):
    @classmethod
    def get(cls):
        argdef = {"type": fields.String(required=True)}
        print(request.args)
        args = parser.parse(argdef, request)
        print(args)


api.add_resource(Test, "/")


with app.test_client() as client:
    res = client.get("/")
    print("post_req: status=" + str(res.status_code))
    print("post_req: data:\n" + res.data.decode("utf-8"))

I think my prior guess that the validation error handler isn’t raising an exception is the best explanation. I’m going to open a PR which adds a warning log statement in that case, but I don’t think there’s anything further we can do here.

0reactions
sirosencommented, Jun 9, 2020

I just took a crack at reproducing this issue without flask-restful and I looked at flask-restful source to see if there was anything obvious they’re doing which might trip us up.

this example, very similar to the provided one, works and fails with a 422
from flask import Flask

from webargs.flaskparser import parser
import marshmallow as ma

website_args = {"type": ma.fields.String(required=True)}

app = Flask(__name__)


@app.route("/func_1")
def func_1():
    print("func_1: start")
    res = parser.parse(website_args)
    print("func_1: parse done")
    print("func_1: res:" + str(res))
    print("func_1: stop")


with app.test_client() as client:
    res = client.get("/func_1")
    print("post_req: status=" + str(res.status_code))
    print("post_req: data:\n" + res.data.decode("utf-8"))

I’ve tried a few variations on this theme with just flask and webargs.

It’s possible that flask-restful is doing something wrong or just unexpected, but my suspicion is that in the OP’s case, flask.abort or parser._on_validation_error aren’t causing exceptions to be raised. Possibly flask-restful changes the behavior of abort? I’m not familiar enough with the framework to say.

I went back over our empty and null body handling for JSON data, and everything seems to lead back to the JSON data being missing, and we later convert that to {} to pass to the schema. But one thing I noticed is that the fallthrough condition for parse could produce None, if the user has defined an error handler which doesn’t raise an exception. I think this is what’s going on.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Why is args.get() returning None in Python? - Stack Overflow
I am trying to get a query parameter by the name of 'indicator_id' but for some reason it is always of type None,...
Read more >
Parsing arguments and building values — Python 3.11.1 ...
If the format string is empty, it returns None ; if it contains exactly one format unit, it returns whatever object is described...
Read more >
5. Parsing Python Arguments
The default value which should return a new reference. The value to return on failure to create a default value, usually -1 or...
Read more >
argparse – Command line option and argument parsing.
For positional, required, arguments, option_string is always None. $ python argparse_custom_action.py Initializing CustomAction dest = 'a' option_strings = ['-a ...
Read more >
Advanced Patterns — Click Documentation (8.1.x)
All eager parameters are evaluated before all non-eager parameters, but again in the order as they were provided on the command line by...
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