webargs

Quickstart

Basic Usage

Arguments are specified as a dictionary of name -> Field pairs.

from webargs import fields, validate

user_args = {

    # Required arguments
    'username': fields.Str(required=True),

    # Validation
    'password': fields.Str(validate=lambda p: len(p) >= 6),

    # OR use marshmallow's built-in validators
    'password': fields.Str(validate=validate.Length(min=6)),

    # Default value when argument is missing
    'display_per_page': fields.Int(missing=10),

    # Repeated parameter, e.g. "/?nickname=Fred&nickname=Freddie"
    'nickname': fields.List(fields.Str()),

    # Delimited list, e.g. "/?languages=python,javascript"
    'languages': fields.DelimitedList(fields.Str())

    # When you know where an argument should be parsed from
    'active': fields.Bool(location='query')

    # When value is keyed on a variable-unsafe name
    # or you want to rename a key
    'content_type': fields.Str(load_from='Content-Type',
                               location='headers')
}

Note

See the marshmallow.fields documentation for a full reference on available field types.

To parse request arguments, use the parse method of a Parser object.

from flask import request
from webargs.flaskparser import parser

@app.route('/register', methods=['POST'])
def register():
    args = parser.parse(user_args, request)
    return register_user(args['username'], args['password'],
        fullname=args['fullname'], per_page=args['display_per_page'])

Decorator API

As an alternative to Parser.parse, you can decorate your view with use_args or use_kwargs. The parsed arguments dictionary will be injected as a parameter of your view function or as keyword arguments, respectively.

from webargs.flaskparser import use_args, use_kwargs

@app.route('/register', methods=['POST'])
@use_args(user_args)  # Injects args dictionary
def register(args):
    return register_user(args['username'], args['password'],
        fullname=args['fullname'], per_page=args['display_per_page'])

@app.route('/settings', methods=['POST'])
@use_kwargs(user_args)  # Injects keyword arguments
def user_settings(username, password, fullname, display_per_page, nickname):
    return render_template('settings.html', username=username, nickname=nickname)

Note

When using use_kwargs, any missing values for non-required fields will take the special value missing.

from webargs import fields, missing

@use_kwargs({'name': fields.Str(), 'nickname': fields.Str(required=False)})
def myview(name, nickname):
    if nickname is missing:
        # ...

Request “Locations”

By default, webargs will search for arguments from the URL query string (e.g. "/?name=foo"), form data, and JSON data (in that order). You can explicitly specify which locations to search, like so:

@app.route('/register')
@use_args(user_args, locations=('json', 'form'))
def register(args):
    return 'registration page'

Available locations include:

  • 'querystring' (same as 'query')
  • 'json'
  • 'form'
  • 'headers'
  • 'cookies'
  • 'files'

Validation

Each Field object can be validated individually by passing the validate argument.

from webargs import fields

args = {
    'age': fields.Int(validate=lambda val: val > 0)
}

The validator may return either a boolean or raise a ValidationError.

from webargs import fields, ValidationError

def must_exist_in_db(val):
    if not User.query.get(val):
        # Optionally pass a status_code
        raise ValidationError('User does not exist')

argmap = {
    'id': fields.Int(validate=must_exist_in_db)
}

Note

If a validator returns None, validation will pass. A validator must return False or raise a ValidationError for validation to fail.

Note

You may pass a list of validators to the validate parameter.

Note

You may pass an HTTP status code to ValidationError.

def must_exist_in_db(val):
    if not User.query.get(val):
        # Optionally pass a status_code
        raise ValidationError('User does not exist', status_code=404)

argmap = {
    'id': fields.Int(validate=must_exist_in_db)
}

The full arguments dictionary can also be validated by passing validate to Parser.parse, Parser.use_args, Parser.use_kwargs.

from webargs import fields
from webargs.flaskparser import parser

argmap = {
    'age': fields.Int(),
    'years_employed': fields.Int(),
}

# ...
result = parser.parse(argmap,
                      validate=lambda args: args['years_employed'] < args['age'])

Error Handling

Each parser has a default error handling method. To override the error handling callback, write a function that receives an error and handles it, then decorate that function with Parser.error_handler.

from webargs import core
parser = core.Parser()

class CustomError(Exception):
    pass

@parser.error_handler
def handle_error(error):
    raise CustomError(error.messages)

Nesting Fields

Field dictionaries can be nested within each other. This can be useful for validating nested data.

from webargs import fields

args = {
    'name': fields.Nested({
        'first': fields.Str(required=True),
        'last': fields.Str(required=True),
    })
}

Note

By default, webargs only parses nested fields using the json request location. You can, however, implement your own parser to add nested field functionality to the other locations.

Next Steps

  • Go on to Advanced Usage to learn how to add custom location handlers, use marshmallow Schemas, and more.
  • See the Framework Support page for framework-specific guides.
  • For example applications, check out the examples directory.