Codebase list python-webargs / bcd95e2 docs / quickstart.rst
bcd95e2

Tree @bcd95e2 (Download .tar.gz)

quickstart.rst @bcd95e2view markup · raw · history · blame

Quickstart

Basic Usage

Arguments are specified as a dictionary of name -> :class:`Field <marshmallow.fields.Field>` pairs.

System Message: INFO/1 (<string>, line 7)

No role entry for "class" in module "docutils.parsers.rst.languages.en". Trying "class" as canonical role name.

System Message: ERROR/3 (<string>, line 7); backlink

Unknown interpreted text role "class".
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"),
    # OR, on marshmallow 3
    # "content_type": fields.Str(data_key="Content-Type", location="headers"),
    # File uploads
    "profile_image": fields.Field(
        location="files", validate=lambda f: f.mimetype in ["image/jpeg", "image/png"]
    ),
}

Note

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

To parse request arguments, use the :meth:`parse <webargs.core.Parser.parse>` method of a :class:`Parser <webargs.core.Parser>` object.

System Message: INFO/1 (<string>, line 43)

No role entry for "meth" in module "docutils.parsers.rst.languages.en". Trying "meth" as canonical role name.

System Message: ERROR/3 (<string>, line 43); backlink

Unknown interpreted text role "meth".

System Message: INFO/1 (<string>, line 43)

No role entry for "class" in module "docutils.parsers.rst.languages.en". Trying "class" as canonical role name.

System Message: ERROR/3 (<string>, line 43); backlink

Unknown interpreted text role "class".
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 :meth:`use_args <webargs.core.Parser.use_args>` or :meth:`use_kwargs <webargs.core.Parser.use_kwargs>`. The parsed arguments dictionary will be injected as a parameter of your view function or as keyword arguments, respectively.

System Message: INFO/1 (<string>, line 65)

No role entry for "meth" in module "docutils.parsers.rst.languages.en". Trying "meth" as canonical role name.

System Message: ERROR/3 (<string>, line 65); backlink

Unknown interpreted text role "meth".

System Message: INFO/1 (<string>, line 65)

No role entry for "meth" in module "docutils.parsers.rst.languages.en". Trying "meth" as canonical role name.

System Message: ERROR/3 (<string>, line 65); backlink

Unknown interpreted text role "meth".
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 will be omitted from the arguments. Use **kwargs to handle optional arguments.

from webargs import fields, missing


@use_kwargs({"name": fields.Str(required=True), "nickname": fields.Str(required=False)})
def myview(name, **kwargs):
    if "nickname" not in kwargs:
        # ...
        pass

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 :class:`Field <marshmallow.fields.Field>` object can be validated individually by passing the validate argument.

System Message: INFO/1 (<string>, line 129)

No role entry for "class" in module "docutils.parsers.rst.languages.en". Trying "class" as canonical role name.

System Message: ERROR/3 (<string>, line 129); backlink

Unknown interpreted text role "class".
from webargs import fields

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

The validator may return either a boolean or raise a :exc:`ValidationError <webargs.core.ValidationError>`.

System Message: INFO/1 (<string>, line 137)

No role entry for "exc" in module "docutils.parsers.rst.languages.en". Trying "exc" as canonical role name.

System Message: ERROR/3 (<string>, line 137); backlink

Unknown interpreted text role "exc".
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")


args = {"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 <webargs.core.ValidationError> for validation to fail.

There are a number of built-in validators from marshmallow.validate <marshmallow.validate> (re-exported as webargs.validate).

from webargs import fields, validate

args = {
    "name": fields.Str(required=True, validate=[validate.Length(min=1, max=9999)]),
    "age": fields.Int(validate=[validate.Range(min=1, max=999)]),
}

The full arguments dictionary can also be validated by passing validate to :meth:`Parser.parse <webargs.core.Parser.parse>`, :meth:`Parser.use_args <webargs.core.Parser.use_args>`, :meth:`Parser.use_kwargs <webargs.core.Parser.use_kwargs>`.

System Message: INFO/1 (<string>, line 170)

No role entry for "meth" in module "docutils.parsers.rst.languages.en". Trying "meth" as canonical role name.

System Message: ERROR/3 (<string>, line 170); backlink

Unknown interpreted text role "meth".

System Message: INFO/1 (<string>, line 170)

No role entry for "meth" in module "docutils.parsers.rst.languages.en". Trying "meth" as canonical role name.

System Message: ERROR/3 (<string>, line 170); backlink

Unknown interpreted text role "meth".

System Message: INFO/1 (<string>, line 170)

No role entry for "meth" in module "docutils.parsers.rst.languages.en". Trying "meth" as canonical role name.

System Message: ERROR/3 (<string>, line 170); backlink

Unknown interpreted text role "meth".
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, the request, the marshmallow.Schema instance, status code, and headers. Then decorate that function with :func:`Parser.error_handler <webargs.core.Parser.error_handler>`.

System Message: INFO/1 (<string>, line 189)

No role entry for "func" in module "docutils.parsers.rst.languages.en". Trying "func" as canonical role name.

System Message: ERROR/3 (<string>, line 189); backlink

Unknown interpreted text role "func".
from webargs import flaskparser

parser = flaskparser.FlaskParser()


class CustomError(Exception):
    pass


@parser.error_handler
def handle_error(error, req, schema, status_code, headers):
    raise CustomError(error.messages)

Parsing Lists in Query Strings

Use fields.DelimitedList <webargs.fields.DelimitedList> to parse comma-separated lists in query parameters, e.g. /?permissions=read,write

from webargs import fields

args = {"permissions": fields.DelimitedList(fields.Str())}

If you expect repeated query parameters, e.g. /?repo=webargs&repo=marshmallow, use fields.List <marshmallow.fields.List> instead.

from webargs import fields

args = {"repo": fields.List(fields.Str())}

Nesting Fields

:class:`Field <marshmallow.fields.Field>` dictionaries can be nested within each other. This can be useful for validating nested data.

System Message: INFO/1 (<string>, line 232)

No role entry for "class" in module "docutils.parsers.rst.languages.en". Trying "class" as canonical role name.

System Message: ERROR/3 (<string>, line 232); backlink

Unknown interpreted text role "class".
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, :ref:`implement your own parser <custom-parsers>` to add nested field functionality to the other locations.

System Message: INFO/1 (<string>, line 246)

No role entry for "ref" in module "docutils.parsers.rst.languages.en". Trying "ref" as canonical role name.

System Message: ERROR/3 (<string>, line 246); backlink

Unknown interpreted text role "ref".

Next Steps

  • Go on to :doc:`Advanced Usage <advanced>` to learn how to add custom location handlers, use marshmallow Schemas, and more.

    System Message: INFO/1 (<string>, line 251)

    No role entry for "doc" in module "docutils.parsers.rst.languages.en". Trying "doc" as canonical role name.

    System Message: ERROR/3 (<string>, line 251); backlink

    Unknown interpreted text role "doc".

  • See the :doc:`Framework Support <framework_support>` page for framework-specific guides.

    System Message: INFO/1 (<string>, line 252)

    No role entry for "doc" in module "docutils.parsers.rst.languages.en". Trying "doc" as canonical role name.

    System Message: ERROR/3 (<string>, line 252); backlink

    Unknown interpreted text role "doc".

  • For example applications, check out the examples directory.