gpt4 book ai didi

python - 如何减慢异步 API 调用以匹配 API 限制?

转载 作者:行者123 更新时间:2023-12-01 09:06:32 28 4
gpt4 key购买 nike

我有一个大约 300K URL 的列表,用于我需要从中获取数据的 API。

API 限制为每秒 100 次调用。

我已经为异步创建了一个类,但是它运行得太快,并且我在 API 上遇到了错误。

如何减慢异步速度,以便每秒可以进行 100 次调用?

import grequests

lst = ['url.com','url2.com']

class Test:
def __init__(self):
self.urls = lst

def exception(self, request, exception):
print ("Problem: {}: {}".format(request.url, exception))

def async(self):
return grequests.map((grequests.get(u) for u in self.urls), exception_handler=self.exception, size=5)



def collate_responses(self, results):
return [x.text for x in results]

test = Test()
#here we collect the results returned by the async function
results = test.async()
response_text = test.collate_responses(results)

最佳答案

我采取的第一步是创建一个对象,该对象每 t 毫秒最多可以分发 n 个硬币。

import time

class CoinsDistribution:
"""Object that distribute a maximum of maxCoins every timeLimit ms"""
def __init__(self, maxCoins, timeLimit):
self.maxCoins = maxCoins
self.timeLimit = timeLimit
self.coin = maxCoins
self.time = time.perf_counter()


def getCoin(self):
if self.coin <= 0 and not self.restock():
return False

self.coin -= 1
return True

def restock(self):
t = time.perf_counter()
if (t - self.time) * 1000 < self.timeLimit:
return False
self.coin = self.maxCoins
self.time = t
return True

现在我们需要一种方法来强制函数仅在可以获得硬币时才被调用。为此,我们可以编写一个装饰器函数,我们可以这样使用:

@limitCalls(callLimit=1, timeLimit=1000)
def uniqFunctionRequestingServer1():
return 'response from s1'

但有时,多个函数正在调用请求同一服务器,因此我们希望它们从同一个 CoinsDistribution 对象获取硬币。因此,装饰器的另一种用途是提供 CoinsDistribution 对象:

server_2_limit = CoinsDistribution(3, 1000)

@limitCalls(server_2_limit)
def sendRequestToServer2():
return 'it worked !!'

@limitCalls(server_2_limit)
def sendAnOtherRequestToServer2():
return 'it worked too !!'

我们现在必须创建装饰器,它可以采用 CoinsDistribution 对象或足够的数据来创建新的装饰器。

import functools

def limitCalls(obj=None, *, callLimit=100, timeLimit=1000):
if obj is None:
obj = CoinsDistribution(callLimit, timeLimit)

def limit_decorator(func):
@functools.wraps(func)
def limit_wrapper(*args, **kwargs):
if obj.getCoin():
return func(*args, **kwargs)
return 'limit reached, please wait'
return limit_wrapper
return limit_decorator

完成了!现在,您可以限制您使用的任何 API 的调用次数,并且如果您必须管理大量 CoinsDistribution 对象(针对不同的 API 端点或不同的 API),您可以构建一个字典来跟踪您的 CoinsDistribution 对象。

注意:这里我选择如果没有可用硬币则返回错误消息。您应该根据您的需要调整此行为。

关于python - 如何减慢异步 API 调用以匹配 API 限制?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52004801/

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