Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the type annotation for a Flask view?

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("/")
like image 964
jh6 Avatar asked Nov 14 '19 19:11

jh6


People also ask

What is a view in Flask?

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 Python?

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.

What's new in Flask 2. 0?

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.

What is decorator in Flask?

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.


2 Answers

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:

  • A str or bytes.
  • A subclass of werkzeug.wrappers.BaseResponse.
  • A tuple in one of these forms, where 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)
  • A dict to be converted to JSON. The values should be types that app.json_encoder supports.
  • A WSGI callable.

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:
    ...
like image 94
davidism Avatar answered Oct 21 '22 07:10

davidism


In Flask 2 you can use flask.typing.ResponseReturnValue.

from flask.typing import ResponseReturnValue


@app.get("/")
def index() -> ResponseReturnValue:
    return "OK"
like image 6
Panic Avatar answered Oct 21 '22 05:10

Panic