Skip to main content

Declarative request parsing and validation for Starlette with webargs

Project description

PyPI version Build status marshmallow 2/3 compatible code style: black

webargs-starlette is a library for declarative request parsing and validation with Starlette, built on top of webargs.

It has all the goodness of webargs, with some extra sugar for type annotations.

import uvicorn
from starlette.applications import Starlette
from starlette.responses import JSONResponse
from webargs_starlette import use_annotations

app = Starlette()


@app.route("/")
@use_annotations(location="query")
async def index(request, name: str = "World"):
    return JSONResponse({"Hello": name})


if __name__ == "__main__":
    uvicorn.run(app, port=5000)

# curl 'http://localhost:5000/'
# {"Hello": "World"}
# curl 'http://localhost:5000/?name=Ada'
# {"Hello": "Ada"}

Install

pip install -U webargs-starlette

Usage

Parser Usage

Use parser.parse to parse a Starlette Request with a dictionary of fields.

from starlette.applications import Starlette
from starlette.responses import JSONResponse
from webargs import fields
from webargs_starlette import parser

app = Starlette()


@app.route("/")
async def homepage(request):
    args = {"name": fields.Str(required=True), "greeting": fields.Str(missing="hello")}
    parsed = await parser.parse(args, request)
    greeting = parsed["greeting"]
    name = parsed["name"]
    return JSONResponse({"message": f"{greeting} {name}"})

Decorators

Use the use_args decorator to inject the parsed arguments dictionary into the handler function. The following snippet is equivalent to the first example.

Important: Decorated functions MUST be coroutine functions.

from starlette.applications import Starlette
from starlette.responses import JSONResponse
from webargs import fields
from webargs_starlette import use_args

app = Starlette()


@app.route("/")
@use_args({"name": fields.Str(required=True), "greeting": fields.Str(missing="hello")})
async def homepage(request, args):
    greeting = args["greeting"]
    name = args["name"]
    return JSONResponse({"message": f"{greeting} {name}"})

The use_kwargs decorator injects the parsed arguments as keyword arguments.

from starlette.applications import Starlette
from starlette.responses import JSONResponse
from webargs import fields
from webargs_starlette import use_args

app = Starlette()


@app.route("/")
@use_kwargs(
    {"name": fields.Str(required=True), "greeting": fields.Str(missing="hello")}
)
async def homepage(request, name, greeting):
    return JSONResponse({"message": f"{greeting} {name}"})

See decorator_example.py for a more complete example of use_args and use_kwargs usage.

Error Handling

When validation fails, the parser will raise a WebargsHTTPException, which is the same as Starlette’s HTTPException with the addition of of the messages (validation messages), headers , exception (underlying exception), and schema (marshmallow Schema) attributes.

You can use a custom exception handler to return the error messages as JSON.

from starlette.responses import JSONResponse
from webargs_starlette import WebargsHTTPException


@app.exception_handler(WebargsHTTPException)
async def http_exception(request, exc):
    return JSONResponse(exc.messages, status_code=exc.status_code, headers=exc.headers)

Annotations

The use_annotations decorator allows you to parse request objects using type annotations.

from starlette.applications import Starlette
from starlette.responses import JSONResponse
from webargs_starlette import use_annotations

app = Starlette()


@app.route("/")
@use_annotations(location="query")
async def welcome(request, name: str = "Friend"):
    return JSONResponse({"message": f"Welcome, {name}!"})


# curl 'http://localhost:5000/'.
# {"message":"Welcome, Friend!"}
# curl 'http://localhost:5000/?name=Ada'.
# {"message":"Welcome, Ada!"}

Any annotated argument that doesn’t have a default value will be required. For example, if we remove the default for name in the above example, an 422 error response is returned if ?name isn’t passed.

from starlette.applications import Starlette
from starlette.responses import JSONResponse
from webargs_starlette import use_annotations, WebargsHTTPException

app = Starlette()


@app.route("/")
@use_annotations(location="query")
async def welcome(request, name: str):
    return JSONResponse({"message": f"Welcome, {name}!"})


@app.exception_handler(WebargsHTTPException)
async def http_exception(request, exc):
    return JSONResponse(exc.messages, status_code=exc.status_code, headers=exc.headers)


# curl "http://localhost:5000/"
# {"name":["Missing data for required field."]}

Arguments may also be annotated with Field instances when you need more control. For example, you may want to add a validator.

from starlette.applications import Starlette
from starlette.responses import JSONResponse
from webargs import fields
from marshmallow import validate
from webargs_starlette import use_annotations, WebargsHTTPException

app = Starlette()


@app.route("/")
@use_annotations(location="query")
async def welcome(request, name: fields.Str(validate=validate.Length(min=2))):
    return JSONResponse({"message": f"Welcome, {name}!"})


@app.exception_handler(WebargsHTTPException)
async def http_exception(request, exc):
    return JSONResponse(exc.messages, status_code=exc.status_code, headers=exc.headers)


# curl "http://localhost:5000/?name=A"
# {"name":["Shorter than minimum length 2."]}

HTTPEndpoint methods may also be decorated with use_annotations.

from starlette.applications import Starlette
from starlette.responses import JSONResponse
from starlette.endpoints import HTTPEndpoint
from webargs_starlette import use_annotations

app = Starlette()


@app.route("/")
class WelcomeEndpoint(HTTPEndpoint):
    @use_annotations(location="query")
    async def get(self, request, name: str = "World"):
        return JSONResponse({"message": f"Welcome, {name}!"})

See annotation_example.py for a more complete example of use_annotations usage.

More

For more information on how to use webargs, see the webargs documentation.

License

MIT licensed. See the LICENSE file for more details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

webargs-starlette-2.0.0.tar.gz (11.2 kB view details)

Uploaded Source

Built Distribution

webargs_starlette-2.0.0-py3-none-any.whl (8.5 kB view details)

Uploaded Python 3

File details

Details for the file webargs-starlette-2.0.0.tar.gz.

File metadata

  • Download URL: webargs-starlette-2.0.0.tar.gz
  • Upload date:
  • Size: 11.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.23.0 setuptools/46.1.3 requests-toolbelt/0.9.1 tqdm/4.46.0 CPython/3.8.2

File hashes

Hashes for webargs-starlette-2.0.0.tar.gz
Algorithm Hash digest
SHA256 6873af91989a186af8aeeee15e38fc976abd17847f6e3ce2bfbd635c7db49414
MD5 d0345c40232043cc3969e5dccba49b82
BLAKE2b-256 f2b8d3d1d33aa72cd712fb2e3d93f6777da096ce3f9971517118b0e34360e7ac

See more details on using hashes here.

Provenance

File details

Details for the file webargs_starlette-2.0.0-py3-none-any.whl.

File metadata

  • Download URL: webargs_starlette-2.0.0-py3-none-any.whl
  • Upload date:
  • Size: 8.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.23.0 setuptools/46.1.3 requests-toolbelt/0.9.1 tqdm/4.46.0 CPython/3.8.2

File hashes

Hashes for webargs_starlette-2.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 932f3f96f5d1dd6f75f2e7bdf7d6e6aa671b8a0ccc30d40007170b22ef286d6f
MD5 8006a2eb1613af71c80b37058f405b4c
BLAKE2b-256 d4404fb999e93d86efef0927da9ed45ae319b04cf69abd9f8e67c9625d033c1a

See more details on using hashes here.

Provenance

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page