不使用Python请求线程调用延迟回调

时间:2017-10-02 13:37:58

标签: python asynchronous python-requests twisted deferred

我正在尝试使用Python中的请求库来执行异步HTTP请求。我发现该库的最后一个版本不直接支持异步请求。为了实现它,它们提供了使用Twisted来处理异步性的请求线程库。我尝试修改提供的示例以使用回调而不是await / yield,但是没有调用回调。

我的示例代码是:

session = AsyncSession(n=10)

def processResponse(response):
  print(response)

def main():
  a = session.get('https://reqres.in/api/users')
  a.addCallbacks(processResponse, processResponse)
  time.sleep(5)

请求线程库:https://github.com/requests/requests-threads

2 个答案:

答案 0 :(得分:2)

我怀疑没有调用回调,因为你没有运行Twisted的eventloop(称为reactor)。删除睡眠功能并将其替换为reactor.run()

from twisted.internet import reactor
# ...
def main():
    a = session.get('https://reqres.in/api/users')
    a.addCallbacks(processResponse, processResponse)
    #time.sleep(5)    # never use blocking functions like this w/ Twisted
    reactor.run()

catch是Twisted的反应器无法重启,所以一旦你停止事件循环(即reactor.stop()),再次执行reactor.run()时会引发异常。换句话说,您的脚本/应用程序只会运行一次"。为避免此问题,我建议您使用crochet。以下是使用requests-thread中的类似示例的快速示例:

import crochet
crochet.setup()
print('setup')

from twisted.internet.defer import inlineCallbacks
from requests_threads import AsyncSession

session = AsyncSession(n=100)

@crochet.run_in_reactor
@inlineCallbacks
def main(reactor):
    responses = []
    for i in range(10):
        responses.append(session.get('http://httpbin.org/get'))

    for response in responses:
        r = yield response
        print(r)

if __name__ == '__main__':
    event = main(None)
    event.wait()

正如FYI requests-thread不适用于生产系统,并且可能会发生重大变化(截至2017年10月)。该项目的最终目标是为将来requests设计一个等待的设计模式。如果您需要生产就绪并发请求,请考虑grequeststreq

答案 1 :(得分:0)

我认为这里唯一的错误就是你忘了运行reactor/event loop

以下代码适用于我:

from twisted.internet import reactor
from requests_threads import AsyncSession

session = AsyncSession(n=10)


def processResponse(response):
    print(response)


a = session.get('https://reqres.in/api/users')
a.addCallbacks(processResponse, processResponse)
reactor.run()