V2.0迁移指南#

urllib3 v2.0 is now available! 请阅读下面的内容,了解如何入门以及新的主要版本中包含哪些内容。

🚀 Migrating from 1.x to 2.0#

我们正在维护 functional API compatibility for most users 让几乎所有人都能轻松选择迁移。大多数更改要么是对默认配置、受支持的Python版本,要么是对内部实现细节的更改。因此,除非您处于特定情况,否则您应该不会注意到任何变化!🎉

备注

如果您在迁移到v2.0或遵循本指南时遇到困难,您可以 open an issue on GitHub 或者把手伸向 our community Discord channel

弃用和破坏性更改的时间表#

2.x的初始发布时间表如下所示:

  • Urllib3 v2.0.0-alpha1 将于2022年11月上映。此版本包含 minor breaking changes and deprecation warnings for other breaking changes 。在v2.0.0发布之前,可能会有其他预发布来解决修复问题。

  • Urllib3 v2.0.0 在对依赖包进行了一些初步集成测试并修复了错误报告后,将于2023年初发布。

  • Urllib3 v2.1.0 将于2023年夏天上映, all breaking changes being warned about in v2.0.0

警告

请拿着 DeprecationWarnings 当从v1.x迁移到v2.0时,您会收到严重的错误消息,因为在2.1.0版本发布后,它们将成为错误。

有哪些重要的变化?#

以下是urllib3 v2.0中哪些更改最重要的简短摘要:

  • Python版本必须为 3.7 or later (以前支持的Python2.7、3.5和3.6)。

  • 删除了对非OpenSSL TLS库(如LibreSSL和wolfSSL)的支持。

  • 删除了对早于1.1.1的OpenSSL版本的支持。

  • 移除了对不是CPython或Py3的Python实现的支持(以前支持的是Google App Engine,Jython)。

  • 删除了 urllib3.contrib.ntlmpool 模块。

  • 不推荐使用 urllib3.contrib.pyopensslurllib3.contrib.securetransport 模块,将在v2.1.0中删除。

  • 不推荐使用 urllib3[secure] 额外的,将在2.1.0版中删除。

  • 不推荐使用 HTTPResponse.getheaders() 赞成的方法 HTTPResponse.headers 将在2.1.0版中删除。

  • 不推荐使用 HTTPResponse.getheader(name, default) 赞成的方法 HTTPResponse.headers.get(name, default) 将在2.1.0版中删除。

  • 不推荐使用不带方案的URL(即‘https://’)‘),并将在未来版本的urllib3中引发错误。

  • 将默认最低TLS版本更改为TLS 1.2(以前为TLS 1.0)。

  • 删除了对通过以下方式验证证书主机名的支持 commonName ,仅限现在 subjectAltName 使用的是。

  • 删除了默认的TLS密码集,现在urllib3使用系统配置的密码列表。

有关更改的完整列表,请查看 the changelog

以包维护人员的身份迁移?#

如果您是一个在幕后使用urllib3的包的维护者,那么这一节是为您准备的。您可能已经看到我们团队中的某个人就即将发布的版本打开了一个问题。

迁移到urllib3v2.x的主要目标应该是确保您的包支持 both urllib3 v1.26.x and v2.0 for some time 。这是为了减少钻石依赖项被引入到用户的依赖项中的可能性,这会导致用户升级到的最新版本时出现问题 your package

支持urllib3 v2.0的第一步是确保v2.x版本不被 install_requires 。您应该确保您的包允许使用urllib3 1.26.x和2.0:

# setup.py (setuptools)
setup(
  ...
  install_requires=["urllib3>=1.26,<3"]
)

# pyproject.toml (hatch)
[project]
dependencies = [
  "urllib3>=1.26,<3"
]

接下来,您应该尝试在本地安装urllib3v2.0并运行您的测试套件。

$ python -m pip install -U --pre 'urllib3>=2.0.0a1'

因为有很多 DeprecationWarnings 您应该确保在运行测试套件时能够看到这些警告。为此,您可以在测试设置中添加以下内容,以确保 DeprecationWarnings 输出到终端:

# Set PYTHONWARNING=default to show all warnings.
$ export PYTHONWARNINGS="default"

# Run your test suite and look for failures.
# Pytest automatically prints all warnings.
$ pytest tests/

或者,您也可以在您的Python代码中选择加入:

# You can change warning filters according to the filter rules:
# https://docs.python.org/3/library/warnings.html#warning-filter
import warnings
warnings.filterwarnings("default", category=DeprecationWarning)

您收到的任何失败或弃用警告都应该得到修复,因为urllib3 v2.1.0将删除所有弃用功能。许多弃用警告将建议如何避免该弃用功能。

警告将如下所示:

DeprecationWarning: 'ssl_version' option is deprecated and will be removed
in urllib3 v2.1.0. Instead use 'ssl_minimum_version'

继续删除不推荐使用的警告,直到不再有警告。在此之后,您可以发布同时支持urllib3v1.26.x和v2.x的包的新版本。

备注

如果您的程序包不能同时支持1.26.x和v2.0的urllib3,请 open an issue on GitHub 或者把手伸向 our community Discord channel

以应用程序开发人员的身份迁移?#

如果您是编写Python的人,但不是以包(如Web服务、数据科学、工具等)的形式发布的,那么这一节适合您。

Python环境只允许为每个环境安装依赖项的一个版本,这意味着 all of your dependencies using urllib3 need to support v2.0 for you to upgrade

可视化依赖项之间关系的最佳方法是使用 pipdeptree$ pipdeptree --reverse

# From inside your Python environment:
$ python -m pip install pipdeptree
# We only care about packages requiring urllib3
$ pipdeptree --reverse | grep "requires: urllib3"

- botocore==1.29.8 [requires: urllib3>=1.25.4,<2]
- requests==2.28.1 [requires: urllib3>=1.21.1,<2]

从上面的输出中可以看到,有两个包依赖于urllib3: botocorerequests 。这两个包的版本都需要低于v2.0的urllib3(即 <2 )。

因为这两个包都需要v2.0之前的urllib3,所以默认情况下不能安装新版本的urllib3。有一些方法可以强制安装较新版本的urllib3 v2.0(即固定到 urllib3==2.0.0 ),您可以这样做来测试您的应用程序。

重要的是要知道,即使您不立即将所有服务升级到2.x,您也会 receive security fixes on the 1.26.x release stream <#security-fixes-for-urllib3-v1-26-x> 有一段时间了。

Urllib3 v1.26.x的安全修复#

多亏了来自 Tidelift 我们能够继续支持v1.26.x发布流,并为可预见的未来💖提供安全修复

但是,仍然建议升级,因为 no new feature developments or non-critical bug fixes will be shipped to the 1.26.x release stream

如果您的组织依赖urllib3并对继续提供支持感兴趣,您可以了解有关 Tidelift Subscription for Enterprise

🤔 Common upgrading issues#

使用OpenSSL 1.0.2.k-FIPS编译了SSL模块#

ImportError: urllib3 v2.0 only supports OpenSSL 1.1.1+, currently the 'ssl' module is compiled with 'OpenSSL 1.0.2k-fips  26 Jan 2017'.
See: https://github.com/urllib3/urllib3/issues/2168

补救措施取决于您的系统:

  • AWS Lambda :升级到Python3.10运行时,因为它使用OpenSSL1.1.1。或者,您可以使用 custom Docker image 并确保您使用的是使用OpenSSL1.1.1或更高版本的Python版本。

  • Amazon Linux 2 :升级到 Amazon Linux 2023 。或者,您可以使用以下命令在Amazon Linux 2上安装OpenSSL 1.1.1 yum install openssl11 openssl11-devel 然后使用类似pyenv的工具安装Python。

  • Red Hat Enterpritse Linux 7 (RHEL 7) :升级到RHEL 8或RHEL 9。

  • Read the Docs :升级您的 configuration file to use Ubuntu 22.04 通过使用 os: ubuntu-22.04build 一节。您可以随时使用 urllib3 configuration 作为一种激励。

Docker.errors.dockerException:获取服务器API版本时出错:请求()获得意外的关键字参数‘chunked’#

升级到 docker==6.1.0 这与urllib32.0兼容。

ImportError:无法从‘REQUESTS_TOOLBETAIN._COMPAT’导入名称‘gaecontrib’#

为了与urllib3 2.0兼容,需要不支持Google App Engine Standard Python2.7的工具带发布版本1.0.0。报告此问题的大多数用户都在使用 Pyrebase 为Firebase API提供API的库。此库未进行维护,但 replacements exist

ImportError: cannot import name 'DEFAULT_CIPHERS' from 'urllib3.util.ssl_'#

这很可能是因为您使用的botocore does not support urllib3 2.0 yet 。好消息是botocore在其依赖项中明确声明它只支持 urllib3<2 。一定要用最新的管子。这样,pip将安装urllib3 1.26.x,直到botocore开始支持urllib3 2.0。

如果要部署到Lambda等AWS环境或使用Amazon Linux 2的主机,则需要明确指定 urllib3<2 在您的项目中,以确保不会将urllib32.0引入您的环境。否则,这可能会对默认的boto3安装产生意想不到的副作用。

AttributeError:模块‘urllib3.Connectionpool’没有属性‘VerifiedHTTPSConnection’#

这个 VerifiedHTTPSConnection 类始终记录为位于 connection 模块。以前可以从以下位置导入 connectionpool 但由于urllib32.0中的重构,这是不可能的,而且不再可能。

请注意,这个类的新名称是 HTTPSConnection 。它可以从urllib3 1.25.9开始使用。

AttributeError:“HTTPResponse”对象没有属性“”Strong“”#

这个 strict 在Python3中不需要该参数,应将其删除。

固定urllib3<2#

如果以上各节的建议都不起作用,您可以通过安装 urllib3<2 。请便 not 指定 urllib3==1.26.15 以确保您继续获得1.26.x更新!

虽然urllib3 1.26.x仍然被支持,但它不会获得新的功能或错误修复,只会得到安全更新。考虑在未来打开一个跟踪问题来解锁urllib3,这样就不会无限期地停留在1.26.x上。有关通常处理依赖项的推荐方法的更多详细信息,请参见 Semantic Versioning Will Not Save You 。下半场甚至以urllib3 2.0为例!

💪 User-friendly features#

Urllib3一直将自己标榜为 user-friendly HTTP client library 。本着更加用户友好的精神,我们添加了两个功能,这应该会使使用urllib3进行修补会话、丢弃脚本和较小项目变得轻而易举!

Urllib3.request()#

以前,urllib3可用的最高级别API是 PoolManager ,但在许多情况下,配置池管理器是没有好处的额外步骤。为了尽可能简单地使用urllib3,我们添加了一个顶级函数,用于从全局poolManager实例发送请求:

>>> import urllib3
>>> resp = urllib3.request("GET", "https://example.com")
>>> resp.status
200

JSON支持请求和响应#

JSON无处不在--现在它也在urllib3中!

如果希望在请求体中发送JSON或将响应正文从JSON反序列化为Python对象,现在可以使用新的 json= 参数用于请求和 HTTPResponse.json() 回应的方法:

import urllib3

# Send a request with a JSON body.
# This adds 'Content-Type: application/json' by default.
resp = urllib3.request(
    "POST", "https://example.api.com",
    json={"key": "value"}
)

# Receive a JSON body in the response.
resp = urllib3.request("GET", "https://xkcd.com/2347/info.0.json")

# There's always an XKCD...
resp.json()
{
  "num": 2347,
  "img": "https://imgs.xkcd.com/comics/dependency.png",
  "title": "Dependency",
  ...
}

✨ Optimized for Python 3.7+#

在V2.0中,我们将专门针对CPython3.7+和PyPy7.0+(与CPython3.7兼容),并放弃对版本2.7、3.5和3.6的支持。

通过放弃生命周期结束的Python版本,我们能够通过使用新功能来优化Python3.7+的代码库,以提高性能并减少为支持遗留版本而需要执行的代码量。

📜 Type-hinted APIs#

您终于能够使用urllib3对代码运行Mypy或其他类型检查器了。这也意味着,对于支持类型提示的IDE,您将从自动完成收到更好的建议。不再与 **kwargs 好了!

我们还添加了API接口,如 BaseHTTPResponseBaseHTTPConnection 为了确保在对接口进行子类化时,您只使用受支持的公共API来确保兼容性并将中断降至最低。

备注

如果您是为数不多的为数不多的对联系或响应进行子类化的人之一,那么您应该仔细查看 the changelog

🔐 Modern security by default#

HTTPS需要TLS 1.2+#

超过95%的网站支持TLS 1.2或以上。在这一点上,我们可以放心地将默认的最低TLS版本切换为1.2,以确保在不中断服务的情况下为用户提供高安全性。

默认情况下,删除TLS 1.0和1.1意味着,如果在未来发现TLS 1.0或1.1中的漏洞,您将不会容易受到TLS降级攻击。免费提供额外的安全保护!通过放弃TLS 1.0和TLS 1.1,我们还收紧了需要支持的密码列表,以确保通过网络传输的数据的高度安全性。

如果您仍然需要在您的应用程序中使用TLS 1.0或1.1,您仍然可以升级到v2.0,您只需设置 ssl_minimum_version 设置为适当的值以继续使用旧版TLS版本。

停止验证证书中的CommonName#

放弃长期不受欢迎的支持 commonName 证书上的字段,支持仅验证 subjectAltName 让我们与浏览器和其他HTTP客户端库保持一致,并提高我们用户的安全性。

通过SSLContext进行证书验证#

默认情况下,证书验证由urllib3处理,以支持遗留的Python版本,但现在我们可以依赖于Python的证书验证!这应该会加速验证证书,并意味着在Python或OpenSSL中对证书验证所做的任何改进都将立即可用。