【问题标题】:How can I write a package that has async methods?如何编写具有异步方法的包?
【发布时间】:2017-03-16 00:36:10
【问题描述】:

我需要编写一个适用于 2.7 和 3.x 的包。该包需要具有以异步方式发出发布请求的方法。这可能吗?我尝试使用 request-futures,但是当我尝试发出多个请求时出现错误。我也尝试过 grequests,但我什至无法让它发出请求。

看起来像这样:

my_package.py

def _make_request(payload):
    requests.post(
        SERVICE_URL,
        data=json.dumps(payload),
    )

def do_thing_a():
    _make_request(some_payload)

def do_thing_b():
    _make_request(some_other_payload)

code_that_uses_my_package.py

    do_thing_a()
    do_thing_b()

如果我同步使用请求,这可以正常工作。如果我使用 requests-futures,只需添加该行 session = FuturesSession() 到每个方法并将 requests.post 更改为 session.post,我收到此错误。

TypeError: 'NoneType' object is not callable
<async at 0x3f657f0> failed with TypeError

如果我只进行一次异步调用,它确实可以工作。 如果我尝试 grequests 并使用 grequests.post + greqeuests.send,什么也不会发生。

我做错了吗?是否有更好的库可用于执行此操作?

【问题讨论】:

  • 需要Twisted 之类的帮助吗?

标签: python python-2.7 python-3.x python-requests


【解决方案1】:

我将回答为什么 grequests 不适合你。使用grequests.send 有点棘手,因为在响应返回之前响应对象将是空的,因此您需要继续检查响应对象,这有点棘手。这可能就是它看起来好像什么都没做的原因。

请改用grequests.map;它在等待响应时不会阻塞,但在所有请求返回之前不会执行下一行。如果您有多个请求,请将它们与grequests.map 一起发送,它们将异步运行。这是您的代码示例的示例:

def _make_request(payload):
    return grequests.post(
        SERVICE_URL,
        data=json.dumps(payload),
    )

def do_thing_a():
    return _make_request(some_payload)

def do_thing_b():
    return _make_request(some_other_payload)

reqs = [do_thing_a(), do_thing_b()]
grequests.map(reqs)
print reqs[0].response, reqs[1].response

req 不必包含多个请求,它可以是具有单个元素的列表。如果您有兴趣在收到多个请求时获得响应,请查看 grequests.imap

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-17
    相关资源
    最近更新 更多