got*_*nes 9 python web-services rate-limiting
我正在开发一个与Web服务API接口的Python库.像我遇到的许多Web服务一样,这个服务请求限制请求的速率.我想limit
为类实例提供一个可选参数,如果提供的话,它将保存传出请求,直到指定的秒数通过.
我理解一般情况如下:类的实例通过方法发出请求.当它发生时,该方法发出一些信号,在某处设置一个锁定变量,并开始倒数计时器的秒数limit
.(很可能,锁定是倒数计时器本身.)如果在此时间范围内发出另一个请求,它必须排队,直到倒数计时器达到零并且锁定被解除; 此时,队列中最早的请求被发送,倒计时器被重置并重新锁定锁定.
这是线程的情况吗?我还没有看到另一种方法吗?
倒计时器和锁定应该是实例变量,还是它们属于该类,以便该类的所有实例都保存请求?
另外,在库中提供速率限制功能通常是个坏主意吗?我的理由是,默认情况下,倒计时为零秒,库仍然允许开发人员使用库并提供他们自己的速率限制方案.鉴于任何使用该服务的开发人员都需要对请求进行速率限制,但我认为,为图书馆提供速率限制手段会更方便.
无论在库中是否设置了速率限制方案,我都希望使用该库编写应用程序,因此建议的技术将派上用场.
非常感谢您的建议!
克里斯
使用队列和调度程序可以更好地解决这个问题.
您将处理分为两个方面:源和发送.这些可以是单独的线程(如果更容易,则可以是单独的进程).
在源端创建,并在任何速率排队,请求让他们高兴.
在调度方面做到这一点.
获取请求开始时间,s.
将请求出列,通过远程服务处理请求.
获取当前时间,t.睡觉率 - (t - s)秒.
如果要运行直接连接到远程服务的源端,可以执行此操作,并绕过速率限制.这对于使用模拟版本的远程服务进行内部测试很有用.
关于这个的困难部分是为每个可以入队的请求创建一些表示.由于Python Queue几乎可以处理任何事情,因此您无需执行任何操作.
如果您正在使用多处理,则必须将对象腌制以将它们放入管道中.
除非需要,否则不要重新发明轮子。检查很棒的库ratelimit。如果您只是想出于任何原因限制对休息 api 的调用并继续您的生活,那么这是完美的选择。
from datetime import timedelta
from ratelimit import limits
import requests
@limits(calls=1, period=timedelta(seconds=60).total_seconds())
def get_foobar():
response = requests.get(url)
response.raise_for_status()
return response.json()
Run Code Online (Sandbox Code Playgroud)
如果每分钟发出的请求数超过一个,这将阻塞线程。