I want to add type annotations to a view function that returns a call to redirect
. What does redirect
return, and how do I add an annotation for that to my view function?
I thought it might be str
, or the redirect
function, but I'm not sure.
def setalarm() -> redirect:
# Retrieves the information to create new alarms.
return redirect("/")
A view function is the code you write to respond to requests to your application. Flask uses patterns to match the incoming request URL to the view that should handle it. The view returns data that Flask turns into an outgoing response.
What Are Type Annotations? Type annotations — also known as type signatures — are used to indicate the datatypes of variables and input/outputs of functions and methods. In many languages, datatypes are explicitly stated. In these languages, if you don't declare your datatype — the code will not run.
This Flask version provides syntactic sugar that allows you to register routes for the most common HTTP methods ( GET , POST , PUT , DELETE , and PATCH ) in a more direct way like other frameworks such as FastAPI are doing. If you want to use this, you just have to change your traditional @app. route for a @app.
Understanding Flask decorators A decorator is a function that takes in another function as a parameter and then returns a function. This is possible because Python gives functions special status. A function can be used as a parameter and a return value, while also being assigned to a variable.
The straightforward answer is to annotate your view with whatever you're writing it to return. In your specific example, redirect
returns an instance of werkzeug.wrappers.Response
.
from werkzeug.wrappers import Response
def set_alarm() -> Response:
return redirect()
Rather than figuring out what any given function returns in order to annotate your view, it might seem easier to come up with a Union
annotation that represents anything a Flask view is allowed to return. However, Flask doesn't provide typing information, and its dynamic nature makes representing the possibilities difficult.
By default, a Flask view can return:
str
or bytes
.werkzeug.wrappers.BaseResponse
.data
is any of the other types a Flask view can return:
(data,)
(data, status)
, where status
can be either an int
or a str
or bytes
.(data, headers)
, where headers
is either a dict, iterable of (key, value)
tuples, or a werkzeug.datastructures.Headers
object.(data, status, headers)
dict
to be converted to JSON. The values should be types that app.json_encoder
supports.Flask can support more or different return types by overriding the Flask.make_response
method. The data it can serialize to JSON can be extended by overriding Flask.json_encoder
. If you have customized Flask's behavior you'll need to customize the type information as well.
Here's a view_return_type
that represents the possible return types from a Flask view, ignoring JSON typing. Once you define the type, you can annotate any view with it.
import typing as t
from werkzeug.datastructures import Headers
from werkzeug.wrappers import BaseResponse
_str_bytes = t.Union[str, bytes]
_data_type = t.Union[
_str_bytes,
BaseResponse,
t.Dict[str, t.Any],
t.Callable[
[t.Dict[str, t.Any], t.Callable[[str, t.List[t.Tuple[str, str]]], None]], t.Iterable[bytes]
],
]
_status_type = t.Union[int, _str_bytes]
_headers_type = t.Union[
Headers, t.Dict[_str_bytes, _str_bytes], t.Iterable[t.Tuple[_str_bytes, _str_bytes]],
]
view_return_type = t.Union[
_data_type,
t.Tuple[_data_type],
t.Tuple[_data_type, _status_type],
t.Tuple[_data_type, _headers_type],
t.Tuple[_data_type, _status_type, _headers_type],
]
@app.route("/users/<int:id>/")
def user_detail(id: int) -> view_return_type:
...
In Flask 2 you can use flask.typing.ResponseReturnValue
.
from flask.typing import ResponseReturnValue
@app.get("/")
def index() -> ResponseReturnValue:
return "OK"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With