gpt4 book ai didi

python - Flask 路由装饰器类型提示

转载 作者:行者123 更新时间:2023-12-02 18:30:38 25 4
gpt4 key购买 nike

我有一个简单的 Flask 应用程序,我在其中添加了一个装饰器,以确保每个请求上都存在特定的 header 。

import functools
from http import HTTPStatus

import flask
from flask.typing import ResponseReturnType

app = flask.Flask(__name__)


# What type hints should be added to this?
def requires_header(func):
@functools.wraps(func)
def check_headers(*args, **kwargs):
if not flask.request.headers.get("X-Foo"):
flask.abort(HTTPStatus.NOT_FOUND)

return func(*args, **kwargs)

return check_headers


@app.route("/", methods=["GET"])
@requires_header
def root() -> ResponseReturnType:
return flask.jsonify(success=True)


if __name__ == "__main__":
flask.run(host=0.0.0.0, port=3000)

我应该向 requires_header 装饰器添加什么类型提示?

最佳答案

如果您使用 --strict 设置运行 Mypy,则以下是目前输入此内容的最佳方式。。这与@Samwise's answer非常相似。 ,但请注意,TypeVar 绑定(bind)到 Callable[..., Any] 而不是裸露的 Callable (Mypy -- strict 不允许任何未参数化的泛型,即使是作为 TypeVar 的参数)。当涉及 requires_header 的返回类型时,我们还必须帮助 Mypy 解决问题 - 它无法验证我们是否实际上返回我们所说的类型应该会返回,所以我们用 a call to typing.cast 帮助 Mypy 解决问题.

import functools
from http import HTTPS
from typing import Callable, TypeVar, cast, Any

import flask

C = TypeVar('C', bound=Callable[..., Any])

def requires_header(func: C) -> C:
@functools.wraps(func)
def check_headers(*args: Any, **kwargs: Any) -> Any:
if not flask.request.headers.get("X-Foo"):
flask.abort(HTTPStatus.NOT_FOUND)

return func(*args, **kwargs)

return cast(C, check_headers)

上述解决方案显然有其缺陷,但主要是我们不得不使用 Any 的次数,通常应尽可能少使用它。 Python 3.10 有 introduced a new feature专门帮助输入装饰器,ParamSpec。不幸的是,Mypy 尚不支持此功能,但当它支持时,我们将能够像这样输入您的装饰器:

import functools
from http import HTTPS
from typing import Callable, TypeVar, cast, ParamSpec

import flask

P = ParamSpec('P')
R = TypeVar('R')

def requires_header(func: Callable[P, R]) -> Callable[P, R]:
@functools.wraps(func)
def check_headers(*args: P.args, **kwargs: P.kwargs) -> R:
if not flask.request.headers.get("X-Foo"):
flask.abort(HTTPStatus.NOT_FOUND)

return func(*args, **kwargs)

return cast(Callable[P, R], check_headers)

使用ParamSpec也可能会消除装饰器最后一行中cast的需要——但这很难说,因为Mypy不这样做尚不支持该功能,因此遗憾的是尚无法使用!

关于python - Flask 路由装饰器类型提示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69472348/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com