Python 使用twisted和(tx)请求异步下载文件

Python 使用twisted和(tx)请求异步下载文件,python,asynchronous,python-requests,twisted,Python,Asynchronous,Python Requests,Twisted,我正在尝试从twisted应用程序中从internet下载文件。由于它直接提供了其他功能或提供了维护良好的库(重试、代理、缓存控制等),因此我希望使用请求来实现这一点。我对twisted only解决方案持开放态度,该解决方案不具备这些功能,但我似乎无论如何都找不到 这些文件应该是相当大的,并且将通过慢速连接下载。因此,我使用了请求'stream=True接口和响应的iter\u内容。这个问题的末尾列出了一个或多或少完整的代码片段。此操作的入口点是http_download函数,使用url调用,

我正在尝试从twisted应用程序中从internet下载文件。由于它直接提供了其他功能或提供了维护良好的库(重试、代理、缓存控制等),因此我希望使用请求来实现这一点。我对twisted only解决方案持开放态度,该解决方案不具备这些功能,但我似乎无论如何都找不到

这些文件应该是相当大的,并且将通过慢速连接下载。因此,我使用了请求'
stream=True
接口和响应的iter\u内容。这个问题的末尾列出了一个或多或少完整的代码片段。此操作的入口点是
http_download
函数,使用
url
调用,使用
dst
将文件写入,使用
回调
和可选的
errback
处理失败的下载。我已经去掉了准备目的地(创建文件夹等)所涉及的一些代码,以及在反应堆退出期间关闭会话的代码,但我认为它仍应按原样工作

这个代码有效。文件下载后,扭曲反应器继续运行。但是,我似乎对这段代码有问题:

def\u流下载(r,f):
对于r.iter\u内容中的区块(区块大小=128):
f、 写入(块)
一无所获
cooperative_dl=cooperative(_stream_download(响应、文件句柄))
因为
iter\u content
只有在有块要返回时才返回,所以反应器处理块,运行其他代码位,然后返回等待下一块,而不是让自己忙于更新GUI上的旋转等待动画(代码实际上没有发布在这里)

问题是-

  • 有没有一种方法可以在发电机本身不准备产生某些东西的情况下,通过扭曲的方式在发电机上运行,从而产生控制?我遇到了一些似乎合适的文档,但这些文档似乎并没有变成扭曲的文档,或者在今天已经不存在了。该问题可以独立于具体内容阅读,即关于任何任意块生成器,也可以在问题的直接上下文中阅读
  • 有没有一种方法可以让twisted使用功能齐全的请求异步下载文件?是否有一个现有的twisted模块,我可以直接使用它
  • 使用twisted解决此类问题的基本方法是什么,它独立于我希望从请求中使用的http特性。让我们假设我准备抛弃它们或以其他方式实施它们。如何通过HTTP异步下载文件
导入操作系统
进口稀土
从functools导入部分
从six.moves.urllib.parse导入urlparse
从请求导入HTTPError
从twisted.internet.task导入
从TXL请求导入会话
类HttpClientMixin(对象):
定义初始化(self,*args,**kwargs):
self.\u http\u session=None
def http_下载(self、url、dst、callback、errback=None、**kwargs):
dst=os.path.abspath(dst)
#日志请求
延迟响应=self.http\u session.get(url,stream=True,**kwargs)
延迟的\u响应。添加回调(self.\u http\u检查\u响应)
延迟的\u响应。添加回调(
部分(自下载,目的地=dst,回调=callback),
部分(self.\u http\u error\u处理程序,url=url,errback=errback)
)
def_http_下载(self、response、destination=None、callback=None):
定义流下载(r,f):
对于r.iter\u内容中的区块(区块大小=128):
f、 写入(块)
一无所获
def_回滚(r、f、d):
如果r:
r、 关闭()
如果f:
f、 关闭()
如果os.path.存在(d):
删除操作系统(d)
filehandle=open(目标“wb”)
cooperative_dl=cooperative(_stream_download(响应、文件句柄))
cooperative_dl.whenDone().addCallback(lambda:response.close)
cooperative_dl.whenDone().addCallback(lambda:filehandle.close)
cooperative_dl.whenDone().addCallback(
部分(回调,url=response.url,destination=destination)
)
合作的_dl.whenDone().addErrback(
部分(_回滚,r=response,f=filehandle,d=destination)
)
def_http_error_处理程序(self、failure、url=None、errback=None):
失败。陷阱(HTTPError)
#日志错误消息
如果返回错误:
错误返回(失败)
@静力学方法
def_http_检查_响应(响应):
响应。针对_状态()提出_
返回响应
@财产
def http_会话(自):
如果不是self.\u http\u会话:
#日志会话启动
self.\u http\u session=session()
返回self.\u http\u会话
有没有一种方法可以在发电机本身不准备产生某些东西的情况下,通过扭曲的方式在发电机上运行,从而产生控制

不,Twisted所能做的就是调用代码。如果代码无限期阻塞,那么调用线程将无限期阻塞。这是Python运行时的基本前提

有没有一种方法可以让twisted使用功能齐全的请求异步下载文件

有一个。您在这里没有说明“全功能”是什么意思,但前面提到了“重试”、“代理”和“缓存控制”。我认为treq目前没有这些功能。您可以在treq文档中找到(尽管我注意到它没有包含您提到的任何功能,即使是请求)。我希望这些特性的实现会受到treq贡献的欢迎

有没有一种方法可以让twisted使用功能齐全的请求异步下载文件

在线程中运行它-可能使用Twisted的线程池API

你会怎么做