Requests: 总超时

创建于 2016-04-16  ·  38评论  ·  资料来源: psf/requests

我们已经充分利用了允许设置每个 TCP 事务超时的超时参数。 这很有帮助! 但是,我们还需要支持整个连接的整体超时。 阅读有关超时的文档,我发现目前不支持此功能,并且至少在一段时间内搜索问题后,我没有看到对此功能的另一个请求——如果有,请原谅。

我意识到我们可以在我们的库中设置计时器来实现这一点,但我担心额外的开销(每个线程一个,我们可能有很多)以及如果我们最终需要中止连接池对连接池的任何不利影响要求。 有没有一种很好的方法来首先中止请求? 我在文档中没有看到任何明显的内容。

所以:从长远来看,如果我们可以在请求库中添加整体超时,那就太好了。 短期内,有没有推荐的方法来实现这一点?

Propose Close

最有用的评论

@jribbens这有一些问题。

第 1 部分是这种补丁的复杂性非常高。 要使其正常运行,您需要在套接字级别重复更改超时。 这意味着补丁需要通过 httplib 普遍传递,我们已经打了比我们想要的更多的补丁。 从本质上讲,我们需要进入 httplib 并重新实现大约 50% 的更复杂的方法,以实现此功能更改。

Part 2 就是这样的补丁维护起来比较麻烦。 为了成功,我们可能需要开始维护相当于 httplib 的并行分支(此时更正确的是 http.client)。 或者,我们需要承担更适合这种变化的不同 HTTP 堆栈的维护负担。 我怀疑,那些希望拥有这样一个特性的人通常会错过这部分:实现它的成本很高,但与在所有平台上支持这样一个特性的持续维护成本相比,这没什么。

第 3 部分是这种补丁的优势尚不清楚。 根据我的经验,大多数想要完全超时补丁的人并没有完全清楚地考虑他们想要什么。 在大多数情况下,总超时参数最终会无缘无故地杀死非常好的请求。

例如,假设您设计了一些下载文件的代码,并且您想处理挂起。 虽然最初很想设置一个固定的总超时(“没有请求可能需要超过 30 秒!”),但这样的超时没有抓住重点。 例如,如果一个文件的大小从 30MB 变为 30GB,则即使下载可能完全正常,也可以_从不_在这种时间间隔内下载此类文件。

换句话说,总超时是一个有吸引力的麻烦:它们似乎可以解决问题,但它们并没有有效地解决问题。 在我看来,一种更有用的方法是利用每个套接字操作的超时,结合stream=Trueiter_content ,并为自己的数据块分配超时。 iter_content的工作方式,控制流将在一定的时间间隔内返回给您的代码。 这意味着您可以为自己设置套接字级别的超时(例如 5 秒),然后在相当小的数据块(例如 1KB 的数据)上设置iter_content ,并且相对有信心,除非您受到主动攻击,否则不会出现拒绝服务在这里是可能的。 如果您真的担心拒绝服务,请将您的套接字级超时设置得更低,并且您的块大小更小(0.5 秒和 512 字节),以确保您定期将控制流交还给您。

所有这一切的结果是,我相信总超时是像这样的库中的一个错误功能。 最好的超时类型是经过调整以允许大响应有足够的时间安静地下载,这种超时最好由套接字级超时和iter_content

所有38条评论

嗨@emgerner-msft,

作为参考,如果不是这个确切的功能请求,以下是这个主题的所有变体:

我们还在https://github.com/sigmavirus24/requests-toolbelt/issues/51上讨论过这个问题

你会注意到最后一个链接讨论了这个包,它应该为你处理这个而不将它添加到请求中。 现实情况是,当另一个包已经做得很好时,不需要请求这样做。

您引用的包通过分叉一个单独的进程来运行 Web 请求来完成它。 这是实现简单的超时目标的一种非常重量级的方式,在我看来,它不能以任何方式替代具有本机超时功能的请求本身。

@jribbens如果您能想出一种既不使用线程也不使用进程的方法,那就太棒了。 在那之前,如果你想要挂钟超时,你最好的选择是那个包,因为它是目前实现它的最可靠的方法。

我不认为@jribbens说没有线程也没有进程。 只是进程_per_ web 请求过多。 许多语言都有多个计时器共享单个附加线程或进程的方法。 我只是不知道如何在 Python 中做到最好。

似乎#1928 对替代方案的讨论最多,但大多数都带有很多警告(这不适用于您的用例等)。 如果这确实不属于请求,我可以在我的库中有一些自定义代码并编写我自己的自定义解决方案,但我认为我需要更多关于它的外观的信息。 我们使用请求的全部原因是为了摆脱低级 TCP 连接池逻辑,但似乎阅读那个线程,为了编写这个自定义代码我需要知道那个逻辑,这就是我遇到的一些麻烦.

@emgerner-msft 是正确的。 我对@sigmavirus24的评论感到有些困惑,在不使用线程或进程的情况下出现“总超时”似乎很普通,而且一点也不“惊人”。 只需计算整个过程开始时的截止日期(例如deadline = time.time() + total_timeout ),然后在任何单个操作上将超时设置为deadline - time.time()

在不使用线程或进程的情况下有一个“总超时”似乎很普通,而且一点也不“惊人”。

而且您的解决方案相当原始。 _most_ 人们想要总(或挂钟)超时的原因是为了防止读取“挂起”,换句话说,如下所示:

r = requests.get(url, stream=True)
for chunk in r.iter_content(chunksize):
    process_data(chunk)

每次读取在iter_content中间需要很长时间,但它小于读取超时(我假设我们在流式传输时应用它,但仍然可能是我们不这样做的情况)他们指定. 当然,这似乎应该由您的解决方案@jribbens简单地处理,直到您记得时钟如何漂移和夏令时工作,并且它们time.time()严重不足。

最后,重要的是要记住 Requests 的 API 是冻结的。 没有用于指定总超时的良好或一致的 API。 如果我们像你建议的那样实现超时,我们会有无数的错误,他们指定一分钟长的总超时,但它需要更长的时间,因为我们上次检查时我们不到一分钟,但他们配置的读取超时足够长以至于他们的超时大约一分半钟出现错误。 这是一个 _very_ 粗略的墙超时,对于寻找这个的人来说会稍微好一些,但与自己实现这个的人没有什么不同。

抱歉,如果我不清楚@sigmavirus24 ,你似乎批评了我的伪代码原理说明,好像你认为它是一个文字补丁。 我应该指出,尽管time.time()不像您显然认为的那样工作 - 夏令时不相关,而且我们在这里谈论的时间尺度上的时钟偏差也不相关。 如果您认为您描述的错误会发生,您也误解了该建议。 最后,我不确定您所说的 Requests API 被“冻结”是什么意思,因为该 API 最近在 2.9.0 版中发生了更改,所以无论您的意思是什么,这不是我通常用这个词所理解的。

只是为了分开我的讨论:我实际上并不是说这很容易。 如果它完全简单,我会写它并停止打扰你。 :)

我的问题是:
1)您列出的线程上的所有内容都是猴子补丁。 这很好,但我在生产质量库中使用它,不能接受内部更改破坏一切的警告。
2)您提供的链接中的超时装饰器很棒,但我不清楚它如何影响连接。 即使我们接受超时的唯一好方法是使用一堆线程,这个库如何强制套接字关闭、连接断开等。我们正在做很多连接,这似乎很有可能容易泄漏。 requests 没有我可以找到的“中止”方法(如果我错了,请纠正我)那么连接的关闭是如何发生的?

我正在寻找的只是一个明确的“有福”的版本,说明如何自己解决这个问题,或者如果没有完美的解决方案,可以讨论一些带有注意事项的解决方案。 那有意义吗?

@emgerner-msft 假设您使用的是 CPython,当请求不再继续时,连接会关闭。 到那时,对底层连接的所有引用都将丢失,套接字将被关闭并处理掉。

@Lukasa好的,谢谢! 图书馆如何确定请求不再继续? 例如,如果我使用超时装饰器路由并在下载中间中断,那么下载何时真正停止? 我需要对流媒体选项做任何特别的事情吗?

如果您使用 timeout 装饰器,下载将在 timeout 触发时停止。 这是因为信号中断了系统调用,这意味着不会有进一步的调用进入套接字。 一旦请求不再在范围内(例如,堆栈已展开到您的requests.*函数之外),那就是:CPython 将清理连接对象并断开连接。 那里不需要特殊的流媒体选项。

完美的。 那么我很高兴关闭线程,除非其他人有更多要说的。

实际上,对不起,还有一个问题。 由于您说它使用信号是相关的,因此正在更仔细地查看超时装饰器代码,而不是像 Python Timers 之类的东西(大概)。 看起来它使用 SIGALRM 调用信号,这在Python Signal中记录在 Windows 上不工作。 我需要它在 Unix 和 Windows 环境以及 Python 2.7 和 3.3+ 中工作(很像请求本身)。 考虑到这一点,我会多花点时间看看这是否真的有效。

@emgerner-msft 这令人沮丧。 =(

@Lukasa是的,尝试了基本用法片段,但它在 Windows 上不起作用。 我阅读了更多代码/示例并进行了修改,看起来如果我们不使用信号包可能会工作,但一切都必须是可挑选的,而我的应用程序并非如此。 据我所知,超时装饰器不会解决我的问题。 还有其他想法吗?

@emgerner-msft 您确定没有任何特定于 Windows 的信号是合适的吗?

@Lukasa坦率地说,我根本不知道。 我以前没有使用过信号,就像我没有意识到直到你告诉我他们会中断请求我不确定什么是合适的。 我也不想让它在 Windows 上工作。 我需要完整的跨平台支持(Windows 和 Unix)以及 Python 2 和 Python 3 支持。 如此多的信号看起来是特定于平台的,这让我很震惊。 Timer是我正在研究的解决方案之一,它看起来不那么低级,因此可能会照顾我的限制,但我不确定我如何关闭连接。 我可以做更多的阅读,但这就是为什么我希望从你们那里得到更多的指导。 :)

所以这是一个非常棘手的地方。

现实情况是,除了中断线程外,几乎没有跨平台的方法可以杀死线程,这基本上就是信号。 这意味着,我认为,信号是你真正必须跨平台进行这项工作的唯一途径。 我倾向于尝试联系 Windowsy Pythony 专家: @brettcannon ,你有什么好的建议吗?

出于兴趣,除了实现和测试它需要工作之外,是否有理由不在请求中实现“总超时”? 我的意思是,如果今天神奇地出现了一个实现它的补丁,理论上它会被拒绝还是被接受? 我赞赏并同意“消除不必要的复杂性”的观点,但“你可以通过分叉一个单独的进程来做到这一点”并没有使这个功能在我看来是不必要的。

@jribbens这有一些问题。

第 1 部分是这种补丁的复杂性非常高。 要使其正常运行,您需要在套接字级别重复更改超时。 这意味着补丁需要通过 httplib 普遍传递,我们已经打了比我们想要的更多的补丁。 从本质上讲,我们需要进入 httplib 并重新实现大约 50% 的更复杂的方法,以实现此功能更改。

Part 2 就是这样的补丁维护起来比较麻烦。 为了成功,我们可能需要开始维护相当于 httplib 的并行分支(此时更正确的是 http.client)。 或者,我们需要承担更适合这种变化的不同 HTTP 堆栈的维护负担。 我怀疑,那些希望拥有这样一个特性的人通常会错过这部分:实现它的成本很高,但与在所有平台上支持这样一个特性的持续维护成本相比,这没什么。

第 3 部分是这种补丁的优势尚不清楚。 根据我的经验,大多数想要完全超时补丁的人并没有完全清楚地考虑他们想要什么。 在大多数情况下,总超时参数最终会无缘无故地杀死非常好的请求。

例如,假设您设计了一些下载文件的代码,并且您想处理挂起。 虽然最初很想设置一个固定的总超时(“没有请求可能需要超过 30 秒!”),但这样的超时没有抓住重点。 例如,如果一个文件的大小从 30MB 变为 30GB,则即使下载可能完全正常,也可以_从不_在这种时间间隔内下载此类文件。

换句话说,总超时是一个有吸引力的麻烦:它们似乎可以解决问题,但它们并没有有效地解决问题。 在我看来,一种更有用的方法是利用每个套接字操作的超时,结合stream=Trueiter_content ,并为自己的数据块分配超时。 iter_content的工作方式,控制流将在一定的时间间隔内返回给您的代码。 这意味着您可以为自己设置套接字级别的超时(例如 5 秒),然后在相当小的数据块(例如 1KB 的数据)上设置iter_content ,并且相对有信心,除非您受到主动攻击,否则不会出现拒绝服务在这里是可能的。 如果您真的担心拒绝服务,请将您的套接字级超时设置得更低,并且您的块大小更小(0.5 秒和 512 字节),以确保您定期将控制流交还给您。

所有这一切的结果是,我相信总超时是像这样的库中的一个错误功能。 最好的超时类型是经过调整以允许大响应有足够的时间安静地下载,这种超时最好由套接字级超时和iter_content

也许@zooba有一个想法,因为他实际上知道 Windows 是如何工作的。 :)

(无关紧要,我最喜欢做的事情之一是在 GitHub 问题中建立一个菊花链专家。)

哈哈,我已经知道@zooba和@brettcannon。 我可以在这里或内部与他们讨论,因为解决这个问题可能也会对他们有所帮助。

@emgerner-msft 我想你可能会,但不想假设:MSFT 是一个大组织!

@Lukasa只是阅读您刚刚在上面写的文字墙 - 有趣! 在讨论 stream=True 和 iter_content 来计时下载时,处理较大上传的等效方法是什么?

_PS_:上面以“换一种方式,..”开头的段落是我在文档中寻找的那种指导。 鉴于您获得的最大超时请求数(以及您不这样做的正当理由),也许最好的办法是在超时文档中添加一些信息?

大声笑@lukasa我同意您关于维护的观点,这已经在我的脑海中,但是关于“功能与错误功能”,恐怕我与您完全相反。 我认为任何_不_想要总超时的人都没有清楚地考虑他们想要什么,而且我很难想象您所描述的错误“30MB 下载更改为 30GB 并因此失败”的情况不是实际上是一个有益的功能!

正如你所说,你可以使用stream=True做一些类似的事情(但我怀疑没有总超时的大部分好处),但我认为请求的重点是它为你处理事情......

我认为请求的重点是它为你处理事情

它为您处理 HTTP。 我们已经处理了连接和读取超时以及我们已经对我们几年的功能冻结有一些豁免的事实与实用性、可取性、一致性(跨多个平台)和可维护性的讨论相切。 我们感谢您的反馈和意见。 如果您有新的信息要介绍,我们将不胜感激。

这也可能表明请求并不能处理所有事情,这个项目上被拒绝的功能请求的数量以及有一个单独的项目为用户实现常见使用模式(请求工具带)的事实。 如果总超时属于任何地方,它会在那里,但同样,它必须在 Windows、BSD、Linux 和 OSX 上工作,并具有出色的测试覆盖率,并且维护起来不会是一场噩梦。

在讨论 stream=True 和 iter_content 来计时下载时,处理较大上传的等效方法是什么?

为您的上传定义一个生成器,并将其传递给data 。 或者,如果分块编码对您来说不是赢家,请使用魔术read方法定义一个类似文件的对象并将 _that_ 传递给data

让我详细说明一下。 如果您将生成器传递给data ,请求将对其进行迭代,并依次发送每个块。 这意味着要发送数据,我们必须将控制流交给每个块的代码。 这使您可以在那段时间内做任何您想做的事情,包括抛出异常以完全中止请求。

如果由于某种原因您不能对上传使用分块传输编码(不太可能,但如果有问题的服务器真的很糟糕,则可能),您可以通过创建一个具有长度的类似文件的对象然后执行您的read调用中的魔法,它将为 8192 字节的块重复调用。 同样,这确保了控制流间歇性地通过您的代码,这使您可以使用自己的逻辑。

PS:上面以“换一种方式,..”开头的段落是我在文档中寻找的那种指导。 鉴于您获得的最大超时请求数(以及您不这样做的正当理由),也许最好的办法是在超时文档中添加一些信息?

我想_。 不过,一般来说,我总是对将一些防御性的文本放入文档中感到紧张。 我猜它可能会进入一个常见问题解答,但是解释为什么我们_不_拥有某些东西的文本在文档中很少有用。 我怀疑,通过做某事的秘诀可以更好地服务文档中的空间。

我认为任何不希望完全超时的人都没有清楚地考虑他们想要什么,而且我很难想象你所描述的错误“30MB 下载更改为 30GB 并因此失败”的情况不是实际上是一个有益的功能!

呵呵,我不是:

  • 包管理器(例如 pip,它使用请求),其中包的数据大小可能有很大差异
  • 网络爬虫,它可能会针对大小差异很大的多个站点运行
  • 一个日志聚合器,它从我们的级别差异很大(因此日志文件大小)的主机下载日志文件
  • 视频下载器(视频大小可能有很大差异)

实际上,我认为开发人员知道他们将要处理的文件大小在一个数量级以内的情况并不常见。 在大多数情况下,开发人员不知道。 通常我会说对这些尺寸做出假设是不明智的。 如果您对下载大小有限制,那么您的代码应该刻意对这些假设进行编码(例如以检查内容长度的形式),而不是隐式编码它们并将它们与用户网络的带宽混合,以便其他人阅读代码可以清楚地看到它们。

但我认为请求的重点是它为你处理事情......

请求非常刻意地不会为用户处理所有事情。 尝试做所有事情是一项不可能完成的任务,并且不可能建立一个好的库来做到这一点。 我们经常告诉用户下拉到 urllib3 以实现某些目标。

只有当我们能比大多数用户做得更好或更简洁时,我们才会将代码放入请求中。 如果没有,就没有价值。 我真的还没有因为总超时作为其中之一而被出售,特别是考虑到我认为在我们的用户群中聚合时相对边际效用。

也就是说,我愿意相信我错了:我只是还没有看到一个令人信服的论据(而且,为了阻止你通过,“我需要它!”不是一个令人信服的论点:必须给出一些理由!)。

@sigmavirus24

如果总超时属于任何地方,它会在那里,但同样,它必须在 Windows、BSD、Linux 和 OSX 上工作,并具有出色的测试覆盖率,并且维护起来不会是一场噩梦。

同意!

@lukasa我想我的想法是,不仅我想要它,事实上几乎所有用户都会想要它,如果他们考虑过它(或者他们没有意识到它还不存在)。 你说应该避免的一半以上的使用场景我会说它很重要(网络爬虫和日志聚合器) - 另外两个不太必要,因为可能有一个用户在等待结果,如果他们可以手动取消下载他们要。 在我看来,任何在没有 UI 的情况下在后台运行并且不使用整体超时的东西都是错误的!

我想我的想法是,不仅我想要它,事实上几乎所有的用户都会想要它,如果他们考虑过它(或者他们没有意识到它还不存在)。

@jribbens我们有几年的时间(如果你结合我们三个人的经验,十年以上)与我们的用户交谈并了解我们的需求。 几乎所有(至少 98%)用户都需要连接和读取超时。 我们知道,我们的一小部分用户希望整体超时。 鉴于我们可以推断出该功能的潜在用户组的规模与不需要该功能的用户的潜在规模以及该功能的维护和开发的复杂性,这并不是我们真正要做的事情去做。

如果您有任何_新_要分享,我们很想听听,但到目前为止您所说的是,在您看来,任何使用请求而没有整体超时的东西都是错误的,我可以想象有很多用户如果您声称他们的设计决策有错误,您会感到生气。 所以,请不要侮辱我们用户的智慧。

@sigmavirus24在整个线程中,你一直在不必要地居高临下、煽动性和粗鲁,我礼貌地问你,请停止。

@Lukasa我详细查看了您关于如何进行流式上传和下载的建议,并阅读了有关这些主题的文档。 如果您可以验证我的假设/问题,那就太好了。

  1. 对于流式下载,如果我使用读取超时“(例如 5 秒)然后在相当小的块(例如 1KB 数据)上使用 iter_content”,这意味着请求库将为每次读取 1KB 应用 5 秒超时,如果它超时需要5s以上。 正确的?
  2. 对于流式上传,如果我使用返回数据块的生成器或类似文件的对象并将读取超时设置为 5 秒,请求库将为我返回的每个块应用 5 秒超时,如果需要更长时间则超时。 正确的?
  3. 如果我不使用生成器进行上传并直接传递字节,请求库如何决定应用我设置的读取超时? 例如,如果我传递了一个 4MB 大小的块和 5 秒的读取超时,那么该读取超时究竟是什么时候应用的?
  4. 如果我不使用 iter_content 并且只是让请求将所有内容直接下载到请求中,读取超时为 5s,那么读取超时究竟是什么时候应用的?

我对套接字 / TCP 协议 / 等有一个大致的了解,但不完全了解 urllib 如何在较低级别使用这些概念,或者请求是否除了传递值之外还有什么特殊的。 我想确切地了解超时是如何应用的,因为简单地让控制流返回并应用我自己的超时方案是行不通的,因为终止线程的跨平台问题。 如果有其他阅读材料可以回答我的问题,请随时向我推荐! 无论如何,这应该是我的最后一组问题。 :)

感谢您一直以来的帮助。

@emgerner-msft 好的:

  1. 不,可悲的是,它比这更复杂。 正如所讨论的,每个超时都应用_per socket call_,但我们不能保证给定块中有多少个套接字调用。 其相当复杂的原因是标准库将支持套接字包装在缓冲区对象中(通常类似于io.BufferedReader )。 这将进行尽可能多的recv_into调用,直到它提供足够的数据。 这可能少至零(如果缓冲区中已经有足够的数据),或者如果远程对等点一次滴灌您一个字节,则与您收到的字节数一样多。 对此我们几乎无能为力:由于对这种缓冲对象的read()调用的性质,我们甚至无法在每个recv_into调用之间获得控制流。

这意味着保证您获得不超过 n 秒等待的唯一方法是使用块大小为1 iter_content 这是下载文件的一种非常低效的方法(在 Python 代码中花费了太多时间),但这是获得所需保证的唯一方法。

  1. 我也相信答案是否定的。 我们目前没有_send_ 超时的概念。 获得一个的方法是使用socket.setdefaulttimeout
  2. 读取超时仅适用于读取,因此您如何传递正文并不重要。
  3. 读取超时与iter_content情况相同:如果您有请求下载所有内容,那么我们最终将发出所需的recv_into调用来下载正文,并且超时适用依次给每个人。

您在这里遇到了核心问题:请求与套接字的距离不够近,无法准确实现您正在寻找的东西。 我们_可以_添加一个发送超时:这是一个功能请求工作考虑,它不会遇到与读取超时相同的问题,但是对于其他所有事情,我们都被卡住了,因为httplib坚持(正确地)交换到缓冲的套接字表示,然后httplib的其余部分使用该缓冲表示。

@卢卡萨

啊,乱七八糟的,哈哈。 我认为可能是这样,但我真的希望我错了。

首先,我们迫切需要发送超时。 我根本无法告诉我的用户他们的上传可以无限挂起,而且我们没有解决问题的计划。 :/

在这一点上,我似乎处于一种不可能的境地。 没有库支持总超时(我明白)。 无法保证现有超时如何与各种块大小一起工作 - 如果有,我可以总结时间:连接超时 + 读取超时 * 块大小。 能够使用流模式和生成器中断流很好,但由于我没有解决方案以跨平台方式实际中止线程,这也无济于事。 您是否看到其他前进的选择? 其他用户正在做什么来解决这些问题?

首先,我们迫切需要发送超时。 我根本无法告诉我的用户他们的上传可以无限挂起,而且我们没有解决问题的计划。 :/

所以请求中使用的超时逻辑基本上是 urllib3 的,所以在那里进行更改就足够了:随时打开功能请求,我们可以帮助您完成更改。 在短期内,请随时使用setdefaulttimeout进行调查。

您是否看到其他前进的选择? 其他用户正在做什么来解决这些问题?

您在此处拥有的选项取决于您的特定限制。

如果您_必须_有一个确定的超时时间(也就是说,如果您必须能够保证一个请求的时间不会超过_n_秒),那么您就不能轻松地使用目前存在的 Python 标准库来做到这一点。 在 Python 2.7 中,您需要修补socket._fileobject以允许您为每个recv调用运行顺序超时,但在 Python 3 中更难,因为您需要修补其实现的类在 C ( io.BufferedReader ) 中,这将是一场噩梦。

否则,获得它的唯一方法是在标准库中关闭缓冲。 这将破坏 httplib 和我们所有的补丁,假设我们可以进行read(x)调用,其行为不像套接字上的read系统调用,而是像read文件上的

换句话说:如果您_需要_确定性超时,您会发现大量库根本无法为您提供。 基本上,如果他们使用httplibsocket.makefile ,那么您将不走运:除了重复发出长度之外,没有干净的方法可以保证控制权在定义的时间内返回给您-1 读取。 你_可以_这样做,但这会损害你的表现。

所以你在这里需要权衡:如果你想要一个确定性的超时,缓冲在 Python 标准库中实现的方式(因此,在请求中)只是不会让你可以使用它。 您可以通过禁用缓冲和重写代码来恢复它,但这可能会严重损害您的性能,除非您以确认超时的方式重新实现缓冲。

您可以在BufferedReader类中的 Python 标准库中实现所需的代码:您绝对可以询问 Python 人员是否感兴趣。 但我不会屏住呼吸。

所以请求中使用的超时逻辑基本上是 urllib3 的,所以在那里进行更改就足够了:随时打开功能请求,我们可以帮助您完成更改。 在短期内,请随意使用 setdefaulttimeout 进行调查。

urllib3 或此处的功能请求? 将尽快打开一个(或两个)。

urllib3 中的功能请求:我们不需要在请求中公开任何新内容。

此页面是否有帮助?
0 / 5 - 0 等级