如何使用 Flask 设置可插入视图的动态限制?

2024-01-16

我一直在致力于一项在烧瓶应用程序上应用节流的任务。对于节流,我一直在研究烧瓶限制器 https://flask-limiter.readthedocs.io/en/stable/。我的应用程序具有从 Flask-restful 的资源扩展的所有端点。

class CompanyApi(Resource):
    decorators = [limiter.limit(limit_value="10/minute")]

    def get(self):
        return "successful"

从 Flask-limiter 文档中,它明确提到可以使用装饰器中的可调用函数来加载基于方法的视图的动态限制。

def get_limit():
   company = request.args.get('company')
   limit = Company.query.get(company)
   #returns a limit string stored in db
   return limit

@app.route("/check_company", methods=["GET"])
@limiter.limit(limit_value=get_limit)
def check_company():
    return "success"

而对于可插入视图,它仅通过将装饰器设置为提供硬编码示例:

decorators = [limiter.limit(limit_value="10/minute")]

我尝试通过在装饰器中设置默认值,并且在处理请求时,我得到请求参数(公司),从中检索限制 D b。然后覆盖限制器的限制值:

CompanyApi.decorators = [Limiter.limit(limit_value=get_limit)]

已经改了,但是没有效果。我需要根据请求动态设置每个端点的限制。

如何为基于类的视图设置动态限制?


我一直在研究烧瓶限制器问题,发现有人尝试过定制限制器 https://github.com/alisaifee/flask-limiter/issues/81#issuecomment-412059668。我找到了一种解决方法来满足我的要求。自定义限制器有以下代码:

class CustomLimiter(Limiter):
    def __init__(self):
        super().__init__(
            key_func=lambda: str(g.user.id) if hasattr(g, 'user') else get_ipaddr(),
            auto_check=False,
        )

    def _evaluate_limits(self, limits):
        failed_limit = None
        limit_for_header = None
        for lim in limits:
            limit_scope = request.endpoint
            limit_key = lim.key_func()
            assert limit_key, 'key expected'
            args = [limit_key, limit_scope]

            if self._key_prefix:
                args = [self._key_prefix] + args
            if not limit_for_header or lim.limit < limit_for_header[0]:
                limit_for_header = [lim.limit] + args
            if not self.limiter.hit(lim.limit, *args):
                self.logger.warning(
                    "ratelimit %s (%s) exceeded at endpoint: %s",
                    lim.limit, limit_key, limit_scope
                )
                failed_limit = lim
                limit_for_header = [lim.limit] + args
                break
        g.view_rate_limit = limit_for_header

        if failed_limit:
            raise RateLimitExceeded(failed_limit.limit)

    def limit(self, limit_value, key_func=None):
        def _inner(obj):
            assert not isinstance(obj, Blueprint)
            func = key_func or self._key_func

            if callable(limit_value):
                limits = [LimitGroup(limit_value, func, None, False, None, None, None)]
            else:
                limits = list(LimitGroup(limit_value, func, None, False, None, None, None))

            @wraps(obj)
            def __inner(*a, **k):
                self._evaluate_limits(limits)
                return obj(*a, **k)
            return __inner
        return _inner


limiter = CustomLimiter()

我添加了一个检查_evaluate_limits:

def _evaluate_limits(self, limits):
        if request:
            company = request.args.get('company')
            limit = Company.query.get(company)
            limits = list(LimitGroup(
                limit,
                get_company_name,  # a callable as a key_func
                None,
                False,
                None,
                None,
                None
            ))
        #.......

在此修改中,每当实例化 Api 时,限制器总是设置要处理的默认限制,但每当有请求时,它都会通过使用 key 函数创建密钥来检查和替换限制。密钥确保计数器下次进行节流。

通过这种方式,我能够实现可插入视图的动态限制行为。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 Flask 设置可插入视图的动态限制? 的相关文章

  • 通过最小元素比较对 5 个元素进行排序

    我必须在 python 中使用元素之间的最小比较次数来建模对 5 个元素的列表进行排序的执行计划 除此之外 复杂性是无关紧要的 结果是一个对的列表 表示在另一时间对列表进行排序所需的比较 我知道有一种算法可以通过 7 次比较 总是在元素之间
  • Flask 会话变量

    我正在用 Flask 编写一个小型网络应用程序 当两个用户 在同一网络下 尝试使用应用程序时 我遇到会话变量问题 这是代码 import os from flask import Flask request render template
  • 从字符串中删除识别的日期

    作为输入 我有几个包含不同格式日期的字符串 例如 彼得在16 45 我的生日是1990年7月8日 On 7 月 11 日星期六我会回家 I use dateutil parser parse识别字符串中的日期 在下一步中 我想从字符串中删除
  • 如何使用 Ansible playbook 中的 service_facts 模块检查服务是否存在且未安装在服务器中?

    我用过service facts检查服务是否正在运行并启用 在某些服务器中 未安装特定的软件包 现在 我如何知道这个特定的软件包没有安装在该特定的服务器上service facts module 在 Ansible 剧本中 它显示以下错误
  • 使用 Tkinter 显示 numpy 数组中的图像

    我对 Python 缺乏经验 第一次使用 Tkinter 制作一个 UI 显示我的数字分类程序与 mnist 数据集的结果 当图像来自 numpy 数组而不是我的 PC 上的文件路径时 我有一个关于在 Tkinter 中显示图像的问题 我为
  • ipython/ pylab/ matplotlib安装和初始化错误

    我在 OS X El Captain 上安装了 matplotlib anaconda ipython 然而 即使在尝试以所有可能的方式设置环境变量之后 我仍无法启动 ipython shell pylab 版本 这是错误 ImportEr
  • 如何使用 OpencV 从 Firebase 读取图像?

    有没有使用 OpenCV 从 Firebase 读取图像的想法 或者我必须先下载图片 然后从本地文件夹执行 cv imread 功能 有什么办法我可以使用cv imread link of picture from firebase 您可以
  • 如何在Python中获取葡萄牙语字符?

    我正在研究葡萄牙语 角色看起来很奇怪 我怎样才能解决这个问题 代码 import feedparser import random Vou definir os feeds feeds conf feedurl http pplware s
  • 添加不同形状的 numpy 数组

    我想添加两个不同形状的 numpy 数组 但不进行广播 而是将 缺失 值视为零 可能最简单的例子是 1 2 3 2 gt 3 2 3 or 1 2 3 2 1 gt 3 2 3 1 0 0 我事先不知道形状 我正在弄乱每个 np shape
  • Python 的“zip”内置函数的 Ruby 等价物是什么?

    Ruby 是否有与 Python 内置函数等效的东西zip功能 如果不是 做同样事情的简洁方法是什么 一些背景信息 当我试图找到一种干净的方法来进行涉及两个数组的检查时 出现了这个问题 如果我有zip 我可以写这样的东西 zip a b a
  • python获取上传/下载速度

    我想在我的计算机上监控上传和下载速度 一个名为 conky 的程序已经在 conky conf 中执行了以下操作 Connection quality alignr wireless link qual perc wlan0 downspe
  • 使用 \r 并打印一些文本后如何清除控制台中的一行?

    对于我当前的项目 有一些代码很慢并且我无法使其更快 为了获得一些关于已完成 必须完成多少的反馈 我创建了一个进度片段 您可以在下面看到 当你看到最后一行时 sys stdout write r100 80 n I use 80覆盖最终剩余的
  • 如何在Python中对类别进行加权随机抽样

    给定一个元组列表 其中每个元组都包含一个概率和一个项目 我想根据其概率对项目进行采样 例如 给出列表 3 a 4 b 3 c 我想在 40 的时间内对 b 进行采样 在 python 中执行此操作的规范方法是什么 我查看了 random 模
  • 向 Altair 图表添加背景实心填充

    I like Altair a lot for making graphs in Python As a tribute I wanted to regenerate the Economist graph s in Mistakes we
  • 使用 VB/ASP classic 可以向 API 发出 HTTP 请求吗?

    是否可以使用 ASP classic 向 Web API 发出请求 例如 像 Flickr API 这样简单的东西 或者这种东西很久以前就不支持了 这是很有可能的 Dim req Set req Server CreateObject MS
  • Scrapy:如何使用元在方法之间传递项目

    我是 scrapy 和 python 的新手 我试图将 parse quotes 中的项目 item author 传递给下一个解析方法 parse bio 我尝试了 request meta 和 response meta 方法 如 sc
  • 在 Qt 中自动调整标签文本大小 - 奇怪的行为

    在 Qt 中 我有一个复合小部件 它由排列在 QBoxLayouts 内的多个 QLabels 组成 当小部件调整大小时 我希望标签文本缩放以填充标签区域 并且我已经在 resizeEvent 中实现了文本大小的调整 这可行 但似乎发生了某
  • 导入错误:没有名为 site 的模块 - mac

    我已经有这个问题几个月了 每次我想获取一个新的 python 包并使用它时 我都会在终端中收到此错误 ImportError No module named site 我不知道为什么会出现这个错误 实际上 我无法使用任何新软件包 因为每次我
  • Python Selenium:如何在文本文件中打印网站上的值?

    我正在尝试编写一个脚本 该脚本将从 tulsaspca org 网站获取以下 6 个值并将其打印在 txt 文件中 最终输出应该是 905 4896 7105 23194 1004 42000 放置的动物 的 HTML span class
  • 如何使用 Pycharm 安装 tkinter? [复制]

    这个问题在这里已经有答案了 I used sudo apt get install python3 6 tk而且效果很好 如果我在终端中打开 python Tkinter 就可以工作 但我无法将其安装在我的 Pycharm 项目上 pip

随机推荐