只是想知道我的想法是否不必要地复杂以及是否有更简单/更好的方法。
我计划使用 Celery 发送请求并从速率受限的 RESTful API 检索数据(每 10 秒 10 个请求)。这是我之前遇到的一个问题的解决方案,我自己编写的 api 包装器(在内部处理速率限制)将为每个视图进行实例化,因此错误地处理了速率限制。
编辑(更多详细信息):
我正在创建一个必须从 RESTful API(即英雄联盟的 API)请求数据的网站。我为 API 编写了一个 python 包装器,它通过计算每个时间间隔发出的请求并等待来处理 API 施加的速率限制。然而,当在 Django 项目中实现我的包装器时,我意识到,当我需要使用 API 时创建包装器类的实例会破坏包装器的速率限制处理,因为每个实例都有单独的请求计数。
我想到的解决方案,可能太复杂,也可能不太复杂,是使用 Celery 来“运行”每个视图都会使用的包装器的单个实例。对于一个看起来非常简单的想法来说,这似乎相对“不合时宜”。也许有一种更简单的方法来始终携带类的单个实例。
迟到的答案,但可以帮助其他人寻找类似的东西,恕我直言,使用
Celery
来管理API包装器的单个实例以处理速率受限的API请求可能是一个可行的解决方案,但我认为这有点复杂,以及过度设计的解决方案。Singleton pattern
包装类中使用
API
。这种模式确保只创建该类的一个实例并在所有视图之间共享。因此,您可以维护一个实例来处理速率限制,而不需要 Celery。这是一个简单的例子:
class MyAPIWrapper:
_instance = None
def __new__(cls):
if cls._instance is None:
cls._instance = super(MyAPIWrapper, cls).__new__(cls)
cls._instance.init()
return cls._instance
def init(self):
# your API here
# Usage:
api_instance = MyAPIWrapper()
在 Django 框架中,您可以创建一个自定义中间件,用于初始化 API 包装器实例并将其存储在请求对象中。这样,您就可以在所需的视图中访问同一实例。通过这种方式,您可以将内容保留在 Django 框架内,而不需要像 Celery 这样的外部工具或库。
此外,您还可以使用 Django 的缓存框架来存储 API 包装器实例,确保它在多个视图中可用。您可以使用 Django 的缓存来存储具有缓存超时的 API 实例,确保在需要时重新创建它。 这里有一些代码:
# api_wrapper.py
class RateLimitedAPIWrapper:
_instance = None
def __new__(cls):
if cls._instance is None:
cls._instance = super(RateLimitedAPIWrapper, cls).__new__(cls)
# rate limiting logic here
return cls._instance
# middleware.py
from .api_wrapper import RateLimitedAPIWrapper
class APIMiddleware:
def __init__(self, get_response):
self.get_response = get_response
self.api_wrapper = RateLimitedAPIWrapper()
def __call__(self, request):
# Make the API wrapper available to all views via request
request.api_wrapper = self.api_wrapper
response = self.get_response(request)
return response
# settings.py
MIDDLEWARE = [
# ...
'yourapp.middleware.APIMiddleware',
# ...
]