如何使用上下文管理器处理API速率限制?

2024-05-08 03:37:32 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图编写一个上下文管理器来处理GitHub速率限制异常。本质上,我希望它监听错误,当它发生时,动态地拉入重置时间(所有操作都是通过GitHubAPI完成的),然后等待这段时间。在这一点上,我希望它恢复程序,并尽可能多次这样做,以完成工作。在

以下是我目前所掌握的情况:

@contextlib.contextmanager
def api_rate_manager(api_obj: g3.GitHub):
    # Check for the API ratelimit being exhausted.  Limited to 5k
    # requests per hour.
    try:
        yield
    except GitHubError as e:
        if 'rate limit exceeded' in e.msg.lower():
            info = g3.rate_limit()['resources']['core']
            reset = mu.convert_unix_timestamp(info.get('reset'))
            delta = reset - datetime.now()
            sleep(
                delta.seconds + 1)  # Add a second to account for milliseconds

目前,它会正确地捕捉到错误并等待,但随后它只会退出程序(这是有意义的),而不是循环返回继续。我知道我可以在代码中检查剩余的限制是多少,如果达到0就等待,但是我想练习上下文管理器。在

它将按以下方式使用:

^{pr2}$

Tags: toinfogithubapi管理器forrate速率
1条回答
网友
1楼 · 发布于 2024-05-08 03:37:32

尽管上下文管理器使用yield(就像在生成器中一样),但它只生成一次。See contextlib's documentation。在

因此,如果在上下文管理器中捕获到异常,则在yield之后继续执行并退出。 您可能希望颠倒上下文管理器和主迭代的顺序。请看下面我的例子。在

上下文管理器:

import contextlib
from time import sleep

@contextlib.contextmanager
def api_rate_manager():
    try:
        yield
    except KeyError as e:
        print('sleeping')
        sleep(3)

测试用例1:

^{pr2}$

输出:

0
2
4
6
sleeping

测试用例2:

for i in range(8):
    with api_rate_manager():
        print(a[i])

输出:

0
2
4
6
sleeping
10
sleeping
sleeping

相关问题 更多 >