Python请求:不要等待请求完成

时间:2014-11-19 16:05:50

标签: python python-requests

在Bash中,可以通过附加&在后​​台执行命令。我怎么能用Python做到这一点?

while True:
    data = raw_input('Enter something: ') 
    requests.post(url, data=data) # Don't wait for it to finish.
    print('Sending POST request...') # This should appear immediately.

6 个答案:

答案 0 :(得分:19)

我使用multiprocessing.dummy.Pool。我在模块级别创建一个单例线程池,然后使用pool.apply_async(requests.get, [params])启动任务。

这个命令给了我一个未来,我可以无限期地添加到其他期货的列表中,直到我想收集全部或部分结果。

对于所有逻辑和原因,

multiprocessing.dummy.Pool是一个THREAD池,而不是一个进程池。

示例(在Python 2和3中都有效,只要安装了请求):

from multiprocessing.dummy import Pool

import requests

pool = Pool(10) # Creates a pool with ten threads; more threads = more concurrency.
                # "pool" is a module attribute; you can be sure there will only
                # be one of them in your application
                # as modules are cached after initialization.

if __name__ == '__main__':
    futures = []
    for x in range(10):
        futures.append(pool.apply_async(requests.get, ['http://example.com/']))
    # futures is now a list of 10 futures.
    for future in futures:
        print(future.get()) # For each future, wait until the request is
                            # finished and then print the response object.

请求将同时执行,因此运行所有这10个请求的时间不应超过最长的请求。这个策略只使用一个CPU核心,但这不应该是一个问题,因为几乎所有的时间都花在等待I / O.

答案 1 :(得分:10)

这是一种愚蠢的方法:

try:
    requests.get("http://127.0.0.1:8000/test/",timeout=0.0000000001)
except requests.exceptions.ReadTimeout: 
    pass

答案 2 :(得分:2)

根据doc,你应该转到另一个图书馆:

  

阻止还是不阻止?

     

使用默认传输适配器,请求不提供   任何类型的非阻塞IO。 Response.content属性将阻止   直到整个响应已下载。如果您需要更多   粒度,库的流功能(请参阅流媒体   请求)允许您检索较小数量的响应   一时间但是,这些调用仍会阻止。

     

如果您担心使用阻塞IO,那么有很多   那些将Requests与Python之一结合起来的项目   异步框架。

     

两个很好的例子   grequests和   requests-futures

答案 3 :(得分:2)

来自Andrew Gorcester的优雅解决方案。此外,无需使用期货,就可以使用callbackerror_callback属性(请参见 doc)以执行异步处理:

def on_success(r: Response):
    if r.status_code == 200:
        print(f'Post succeed: {r}')
    else:
        print(f'Post failed: {r}')

def on_error(ex: Exception):
    print(f'Post requests failed: {ex}')

pool.apply_async(requests.post, args=['http://server.host'], kwargs={'json': {'key':'value'},
                        callback=on_success, error_callback=on_error))

答案 4 :(得分:1)

如果您可以在单独的python程序中单独编写要执行的代码,here是基于子处理的可能解决方案。

否则你可能会发现有用的this question和相关的答案:诀窍是使用线程库来启动一个单独的线程来执行分离的任务。

两种方法的警告可能是您必须管理的项目数(表示线程数)。如果item中的parent太多,您可以考虑暂停每批项目,直到至少某些线程完成,但我认为这种管理非常重要。

对于更复杂的方法,您可以使用基于actor的方法,我自己没有使用过this library,但我认为在这种情况下它可以提供帮助。

答案 5 :(得分:-1)

from multiprocessing.dummy import Pool
import requests

pool = Pool()

def on_success(r):
    print('Post succeed')

def on_error(ex):
    print('Post requests failed')

def call_api(url, data, headers):
    requests.post(url=url, data=data, headers=headers)

def pool_processing_create(url, data, headers):
    pool.apply_async(call_api, args=[url, data, headers], 
    callback=on_success, error_callback=on_error)