2017-03-16 61 views
0

我需要编写一个适用于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() 

如果我使用请求同步能正常工作。如果我使用请求 - 期货,并且将 session = FuturesSession()行添加到每个方法并将requests.post更改为session.post,则会出现此错误。

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

如果我只做一个异步调用,但它确实工作。 如果我尝试使用grequests并使用grequests.post + greqeuests.send,则不会发生任何事情。

我做错了什么?有没有更好的图书馆来做到这一点?

+1

Woiuld像[Twisted](https://twistedmatrix.com/trac/)的帮助? – tadman

回答

0

我会回答为什么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如果你有兴趣获得他们进来的多个请求的回应。