Request Parsing

Flask-RESTful’s request parsing interface, reqparse, is modeled after the argparse interface. It’s designed to provide simple and uniform access to any variable on the flask.request object in Flask.

Basic Arguments

Here’s a simple example of the request parser. It looks for two arguments in the flask.Request.values dict: an integer and a string

from flask_restful import reqparse

parser = reqparse.RequestParser()
parser.add_argument('rate', type=int, help='Rate cannot be converted')
parser.add_argument('name')
args = parser.parse_args()

Note

The default argument type is a unicode string. This will be str in python3 and unicode in python2.

If you specify the help value, it will be rendered as the error message when a type error is raised while parsing it. If you do not specify a help message, the default behavior is to return the message from the type error itself.

By default, arguments are not required. Also, arguments supplied in the request that are not part of the RequestParser will be ignored.

Also note: Arguments declared in your request parser but not set in the request itself will default to None.

Required Arguments

To require a value be passed for an argument, just add required=True to the call to add_argument().

parser.add_argument('name', required=True,
help="Name cannot be blank!")

Multiple Values & Lists

If you want to accept multiple values for a key as a list, you can pass action='append'

parser.add_argument('name', action='append')

This will let you make queries like

curl http://api.example.com -d "name=bob" -d "name=sue" -d "name=joe"

And your args will look like this

args = parser.parse_args()
args['name']    # ['bob', 'sue', 'joe']

Other Destinations

If for some reason you’d like your argument stored under a different name once it’s parsed, you can use the dest keyword argument.

parser.add_argument('name', dest='public_name')

args = parser.parse_args()
args['public_name']

Argument Locations

By default, the RequestParser tries to parse values from flask.Request.values, and flask.Request.json.

Use the location argument to add_argument() to specify alternate locations to pull the values from. Any variable on the flask.Request can be used. For example:

# Look only in the POST body
parser.add_argument('name', type=int, location='form')

# Look only in the querystring
parser.add_argument('PageSize', type=int, location='args')

# From the request headers
parser.add_argument('User-Agent', location='headers')

# From http cookies
parser.add_argument('session_id', location='cookies')

# From file uploads
parser.add_argument('picture', type=werkzeug.datastructures.FileStorage, location='files')

Multiple Locations

Multiple argument locations can be specified by passing a list to location:

parser.add_argument('text', location=['headers', 'values'])

The last location listed takes precedence in the result set.

Parser Inheritance

Often you will make a different parser for each resource you write. The problem with this is if parsers have arguments in common. Instead of rewriting arguments you can write a parent parser containing all the shared arguments and then extend the parser with copy(). You can also overwrite any argument in the parent with replace_argument(), or remove it completely with remove_argument(). For example:

from flask_restful import reqparse

parser = reqparse.RequestParser()
parser.add_argument('foo', type=int)

parser_copy = parser.copy()
parser_copy.add_argument('bar', type=int)

# parser_copy has both 'foo' and 'bar'

parser_copy.replace_argument('foo', required=True, location='json')
# 'foo' is now a required str located in json, not an int as defined
#  by original parser

parser_copy.remove_argument('foo')
# parser_copy no longer has 'foo' argument

Error Handling

The default way errors are handled by the RequestParser is to abort on the first error that occurred. This can be beneficial when you have arguments that might take some time to process. However, often it is nice to have the errors bundled together and sent back to the client all at once. This behavior can be specified either at the Flask application level or on the specific RequestParser instance. To invoke a RequestParser with the bundling errors option, pass in the argument bundle_errors. For example

from flask_restful import reqparse

parser = reqparse.RequestParser(bundle_errors=True)
parser.add_argument('foo', type=int, required=True)
parser.add_argument('bar', type=int, required=True)

# If a request comes in not containing both 'foo' and 'bar', the error that
# will come back will look something like this.

{
    "message":  {
        "foo": "foo error message",
        "bar": "bar error message"
    }
}

# The default behavior would only return the first error

parser = RequestParser()
parser.add_argument('foo', type=int, required=True)
parser.add_argument('bar', type=int, required=True)

{
    "message":  {
        "foo": "foo error message"
    }
}

The application configuration key is “BUNDLE_ERRORS”. For example

from flask import Flask

app = Flask(__name__)
app.config['BUNDLE_ERRORS'] = True

Warning

BUNDLE_ERRORS is a global setting that overrides the bundle_errors option in individual RequestParser instances.