gpt4 book ai didi

python - 使用扭曲和 (tx) 请求异步下载文件

转载 作者:行者123 更新时间:2023-11-28 18:12:42 25 4
gpt4 key购买 nike

我正在尝试从扭曲的应用程序中从 Internet 下载文件。由于它直接提供的其他功能或具有维护良好的库来提供(重试、代理、缓存控制等),我想使用请求来执行此操作。我对没有这些功能的扭曲的唯一解决方案持开放态度,但我似乎无法找到一个。

文件应该相当大,并且将在慢速连接下下载。因此,我使用请求的 stream=True 接口(interface)和响应的 iter_content。这个问题的末尾列出了一个或多或少完整的代码片段。入口点是 http_download 函数,使用 url 调用,将文件写入到的 dstcallback 和一个可选的 errback 来处理失败的下载。我已经删除了一些涉及准备目标(创建文件夹等)的代码和在 react 器退出期间关闭 session 的代码,但我认为它应该仍然可以按原样工作。

此代码有效。文件下载完毕,扭曲的 react 堆继续运转。但是,这段代码似乎有问题:

def _stream_download(r, f):
for chunk in r.iter_content(chunk_size=128):
f.write(chunk)
yield None

cooperative_dl = cooperate(_stream_download(response, filehandle))

因为 iter_content 只有在它有 block 要返回时才返回, react 器处理一个 block ,运行其他代码,然后返回等待下一个 block ,而不是让自己忙于更新旋转在 GUI 上等待动画(此处未实际发布代码)。

这是问题 -

  • 有没有一种方法可以扭曲这个生成器的运行方式,使其在生成器本身不准备生成某些东西时交出控制权?我遇到了 twisted.flow 的一些文档这似乎是合适的,但这似乎并没有使它扭曲或不复存在。这个问题可以独立于细节阅读,即关于任何任意阻塞生成器,或者可以在问题的直接上下文中阅读。
  • 有没有办法使用像请求这样功能齐全的东西来异步下载文件?是否有一个现有的扭曲模块可以做到这一点我可以使用?
  • 解决这种扭曲问题的基本方法是什么,独立于我想从请求中使用的 http 功能。假设我准备放弃它们或以其他方式实现它们。如何通过 HTTP 异步下载文件。
import os
import re
from functools import partial
from six.moves.urllib.parse import urlparse

from requests import HTTPError
from twisted.internet.task import cooperate
from txrequests import Session

class HttpClientMixin(object):
def __init__(self, *args, **kwargs):
self._http_session = None

def http_download(self, url, dst, callback, errback=None, **kwargs):
dst = os.path.abspath(dst)
# Log request
deferred_response = self.http_session.get(url, stream=True, **kwargs)
deferred_response.addCallback(self._http_check_response)
deferred_response.addCallbacks(
partial(self._http_download, destination=dst, callback=callback),
partial(self._http_error_handler, url=url, errback=errback)
)

def _http_download(self, response, destination=None, callback=None):
def _stream_download(r, f):
for chunk in r.iter_content(chunk_size=128):
f.write(chunk)
yield None

def _rollback(r, f, d):
if r:
r.close()
if f:
f.close()
if os.path.exists(d):
os.remove(d)

filehandle = open(destination, 'wb')
cooperative_dl = cooperate(_stream_download(response, filehandle))
cooperative_dl.whenDone().addCallback(lambda _: response.close)
cooperative_dl.whenDone().addCallback(lambda _: filehandle.close)
cooperative_dl.whenDone().addCallback(
partial(callback, url=response.url, destination=destination)
)
cooperative_dl.whenDone().addErrback(
partial(_rollback, r=response, f=filehandle, d=destination)
)

def _http_error_handler(self, failure, url=None, errback=None):
failure.trap(HTTPError)
# Log error message
if errback:
errback(failure)

@staticmethod
def _http_check_response(response):
response.raise_for_status()
return response

@property
def http_session(self):
if not self._http_session:
# Log session start
self._http_session = Session()
return self._http_session

最佳答案

Is there a way to get twisted to operate on this generator in such a way that it yields control when the generator itself is not prepared to yield something?

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

Is there a way to get twisted to download files asynchronously using something full-featured like requests?

treq .您在这里没有说“全功能”是什么意思,但之前您提到了“重试”、“代理”和“缓存控制”。我不认为 treq 当前具有这些功能。你可以找到some kind of feature matrix在 treq 文档中(尽管我注意到它不包含您提到的任何功能 - 即使是请求)。我希望这些功能的实现会受到 treq 贡献的欢迎。

Is there a way to get twisted to download files asynchronously using something full-featured like requests?

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

What would the basic approach be to such a problem with twisted, independent of the http features I want to use from requests.

求求。

关于python - 使用扭曲和 (tx) 请求异步下载文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50269036/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com