Source code for webargs.flaskparser

"""Flask request argument parsing module.

Example: ::

    from flask import Flask

    from webargs import fields
    from webargs.flaskparser import use_args

    app = Flask(__name__)

    user_detail_args = {
        'per_page': fields.Int()
    }

    @app.route("/user/<int:uid>")
    @use_args(user_detail_args)
    def user_detail(args, uid):
        return ("The user page for user {uid}, showing {per_page} posts.").format(
            uid=uid, per_page=args["per_page"]
        )
"""
from __future__ import annotations

import json
import typing

import flask
import marshmallow as ma
from werkzeug.exceptions import HTTPException

from webargs import core


[docs] def abort( http_status_code: int, exc: Exception | None = None, **kwargs: typing.Any ) -> typing.NoReturn: """Raise a HTTPException for the given http_status_code. Attach any keyword arguments to the exception for later processing. From Flask-Restful. See NOTICE file for license information. """ try: flask.abort(http_status_code) except HTTPException as err: err.data = kwargs # type: ignore err.exc = exc # type: ignore raise err
def is_json_request(req: flask.Request) -> bool: return core.is_json(req.mimetype) class FlaskParser(core.Parser[flask.Request]): """Flask request argument parser.""" DEFAULT_UNKNOWN_BY_LOCATION: dict[str, str | None] = { "view_args": ma.RAISE, "path": ma.RAISE, **core.Parser.DEFAULT_UNKNOWN_BY_LOCATION, } __location_map__ = dict( view_args="load_view_args", path="load_view_args", **core.Parser.__location_map__, ) def _raw_load_json(self, req: flask.Request) -> typing.Any: """Return a json payload from the request for the core parser's load_json Checks the input mimetype and may return 'missing' if the mimetype is non-json, even if the request body is parseable as json.""" if not is_json_request(req): return core.missing return core.parse_json(req.get_data(cache=True)) def _handle_invalid_json_error( self, error: json.JSONDecodeError | UnicodeDecodeError, req: flask.Request, *args: typing.Any, **kwargs: typing.Any, ) -> typing.NoReturn: abort(400, exc=error, messages={"json": ["Invalid JSON body."]}) def load_view_args(self, req: flask.Request, schema: ma.Schema) -> typing.Any: """Return the request's ``view_args`` or ``missing`` if there are none.""" return req.view_args or core.missing def load_querystring(self, req: flask.Request, schema: ma.Schema) -> typing.Any: """Return query params from the request as a MultiDictProxy.""" return self._makeproxy(req.args, schema) def load_form(self, req: flask.Request, schema: ma.Schema) -> typing.Any: """Return form values from the request as a MultiDictProxy.""" return self._makeproxy(req.form, schema) def load_headers(self, req: flask.Request, schema: ma.Schema) -> typing.Any: """Return headers from the request as a MultiDictProxy.""" return self._makeproxy(req.headers, schema) def load_cookies(self, req: flask.Request, schema: ma.Schema) -> typing.Any: """Return cookies from the request.""" return req.cookies def load_files(self, req: flask.Request, schema: ma.Schema) -> typing.Any: """Return files from the request as a MultiDictProxy.""" return self._makeproxy(req.files, schema) def handle_error( self, error: ma.ValidationError, req: flask.Request, schema: ma.Schema, *, error_status_code: int | None, error_headers: typing.Mapping[str, str] | None, ) -> typing.NoReturn: """Handles errors during parsing. Aborts the current HTTP request and responds with a 422 error. """ status_code: int = error_status_code or self.DEFAULT_VALIDATION_STATUS abort( status_code, exc=error, messages=error.messages, schema=schema, headers=error_headers, ) def get_default_request(self) -> flask.Request: """Override to use Flask's thread-local request object by default""" return flask.request parser = FlaskParser() use_args = parser.use_args use_kwargs = parser.use_kwargs