仓库

仓库 #

Poetry 支持使用 PyPI 和私有仓库来发现包以及发布你的项目。

默认情况下,Poetry 配置为使用 PyPI 仓库,用于包安装和发布。

因此,当你向你的项目添加依赖项时,Poetry 会假设它们在 PyPI 上可用。

这代表了大多数情况,对于大多数用户来说可能已经足够了。

私有仓库示例 #

从私有包源安装 #

默认情况下,Poetry 从 PyPI 发现和安装包。但是,你想为你的项目安装一个 简单 API 仓库 的依赖项?让我们来做吧。

首先,配置 包源 作为你的项目的 补充(或 显式)包源。

poetry source add --priority=supplemental foo https://pypi.example.org/simple/

然后,假设仓库需要身份验证,为它配置凭据。

poetry config http-basic.foo <username> <password>
警告
根据你的系统配置,凭据可能会保存在你的命令行历史记录中。许多 shell 在命令前缀为空格字符时不会将命令保存到历史记录中。有关更多信息,请参阅你的 shell 文档。
注意

如果你想以交互方式提供密码,你只需在命令中省略 <password>。Poetry 会提示你手动输入凭据。

poetry config http-basic.foo <username>

完成此操作后,你就可以从该源向你的项目添加依赖项了。

poetry add --source foo private-package

发布到私有仓库 #

太好了,现在剩下的就是发布你的包了。假设你想私下与你的团队共享它,你可以配置你的 可发布仓库上传 API 端点。

poetry config repositories.foo https://pypi.example.org/legacy/
注意

如果你需要为你的 包源 使用不同的凭据,那么建议为你的发布仓库使用不同的名称。

poetry config repositories.foo-pub https://pypi.example.org/legacy/
poetry config http-basic.foo-pub <username> <password>
注意

使用环境变量配置仓库时,请注意需要使用正确的后缀。

export POETRY_REPOSITORIES_FOO_URL=https://pypi.example.org/legacy/
export POETRY_HTTP_BASIC_FOO_USERNAME=<username>
export POETRY_HTTP_BASIC_FOO_PASSWORD=<password>

现在,剩下的就是使用 publish 构建和发布你的项目了。

poetry publish --build --repository foo-pub

包源 #

默认情况下,Poetry 配置为使用 Python 生态系统的规范包索引 PyPI

注意
除了为 PyPI 隐式配置的名为 pypi 的源之外,包源是项目本地化的,必须在项目的 pyproject.toml 文件中配置。这与发布包时使用的配置不同

项目配置 #

这些包源可以使用你的项目的 source 命令进行管理。

poetry source add foo https://foo.bar/simple/
注意
如果你的包源需要 凭据证书,请参阅下面相关的部分。

这将在你的 pyproject.toml 文件中生成以下配置片段。

[[tool.poetry.source]]
name = "foo"
url = "https://foo.bar/simple/"
priority = "primary"

如果 priority 未定义,则该源被视为优先于 PyPI、次要、补充和显式源的主要源。

包源按以下顺序考虑

  1. 默认源(已弃用),
  2. 主要源,
  3. 隐式 PyPI(除非被其他 主要源默认源 或显式配置禁用),
  4. 次要源(已弃用),
  5. 补充源.

显式源 仅考虑明确 指示其源 的包。

在每个优先级类别中,包源按其在 pyproject.toml 中出现的顺序考虑。

注意

如果你想更改 PyPI 的优先级,你可以显式设置它,例如:

poetry source add --priority=primary PyPI

如果你希望完全禁用 PyPI,只需添加一个 主源 或将 PyPI 配置为 显式源

默认包源 (已弃用) #

在 1.8.0 中弃用

警告
配置默认包源已弃用,因为它与最顶层的 主源 相同。只需配置一个主包源并将其放在包源列表的首位。

默认情况下,如果你没有配置任何主源,Poetry 将配置 PyPI 作为你项目的包源。你可以更改此行为,并仅从配置的包源中查找包,方法是添加至少一个主源(推荐)或一个带有 priority = "default"单个源(已弃用)。

poetry source add --priority=default foo https://foo.bar/simple/

主包源 #

所有主包源都将被搜索,以查找每个没有 源约束 的依赖项。如果你配置了至少一个主源,则隐式 PyPI 源将被禁用。

poetry source add --priority=primary foo https://foo.bar/simple/

没有优先级的源也被认为是主源。

poetry source add foo https://foo.bar/simple/
警告

如果配置了至少一个主源,则隐式 PyPI 源将自动禁用。如果你想除了主源之外还使用 PyPI,请使用特定优先级显式配置它,例如:

poetry source add --priority=primary PyPI

这样,就可以以细粒度的方式设置 PyPI 的优先级。

pyproject.toml 中的等效规范是

[[tool.poetry.source]]
name = "pypi"
priority = "primary"

在显式指定 PyPI 时省略 url 因为 PyPI 在 Poetry 中是内部配置的,所以 PyPI 存储库不能使用给定的 URL 进行配置。请记住,你始终可以使用 poetry check 来确保 pyproject.toml 文件的有效性。

辅助包源 (已弃用) #

在 1.5.0 中弃用

如果包源被配置为辅助源,这意味着在选择与你的默认和主包源中也存在的兼容包分发时,这些源将被赋予较低的优先级。如果包源应该只在更高优先级的存储库没有返回结果时才被搜索,请考虑使用 补充源

你可以在你的包源配置中使用 priority = "secondary" 将包源配置为辅助源。

poetry source add --priority=secondary foo https://foo.bar/simple/

可以有多个辅助包源。

警告
辅助包源已被弃用,取而代之的是补充包源。

补充包源 #

在 1.5.0 中引入

配置为补充源的包源只有在没有其他(更高优先级)源产生兼容的包分发时才会被搜索。如果源的响应时间很长,并且从该源获取的包分发相对较少,这将特别方便。

你可以在你的包源配置中使用 priority = "supplemental" 将包源配置为补充源。

poetry source add --priority=supplemental foo https://foo.bar/simple/

可以有多个补充包源。

警告
请注意,有人可能会将一个新包发布到主源,该包与你的补充源中的包匹配。他们可能会偶然或有意地用你没有预料到的东西替换你的依赖项。

显式包源 #

在 1.5.0 中引入

如果包源被配置为显式源,则只有在包配置 明确指示 应该在该包源上找到它时,才会搜索这些源。

你可以在你的包源配置中使用 priority = "explicit" 将包源配置为显式源。

poetry source add --priority=explicit foo https://foo.bar/simple/

可以有多个显式包源。

注意

显式包源有用的一个现实世界的例子是 PyTorch GPU 包。

poetry source add --priority=explicit pytorch-gpu-src https://download.pytorch.org/whl/cu118
poetry add --source pytorch-gpu-src torch torchvision torchaudio

包源约束 #

在包查找过程中,将搜索所有包源(包括辅助源和可能存在的补充源)。这些网络请求将针对所有源发生,无论包是否在一个或多个源中找到。

为了将特定包的搜索限制在特定的包存储库中,你可以显式指定源。

poetry add --source internal-pypi httpx

这将导致 pyproject.toml 中的以下配置

[tool.poetry.dependencies]
...
httpx = { version = "^0.22", source = "internal-pypi" }

[[tool.poetry.source]]
name = "internal-pypi"
url = ...
priority = ...
注意
配置为检索特定包的唯一源的存储库本身可以具有任何优先级。特别是,它不需要具有优先级 "explicit"。如果一个存储库被配置为包的源,它将是唯一被考虑的源,存储库优先级将不会影响解析。
注意

source 键不会被其依赖项继承。特别是,如果 package-A 被配置为在 source = internal-pypi 中找到,并且 package-A 依赖于也应该在 internal-pypi 上找到的 package-B,那么 package-B 需要在 pyproject.toml 中进行配置。实现这一点的最简单方法是使用通配符约束添加 package-B

poetry add --source internal-pypi package-B@*

这将确保 package-B 仅在 internal-pypi 包源中被搜索。package-B 上的版本约束将像往常一样从 package-A(和其他客户端包)中派生。

如果你想避免额外的主要依赖项,你可以将 package-B 添加到一个专门的 依赖项组

poetry add --group explicit --source internal-pypi package-B@*
注意
强烈建议对所有预期仅由一个特定源提供的包使用包源约束,以避免依赖项混淆攻击。

支持的包源 #

Python 包索引 (PyPI) #

Poetry 通过其 JSON APIPyPI 交互。这用于检索请求的包的版本、元数据、文件等。

注意
如果包发布的元数据无效,Poetry 将下载可用的 bdist/sdist 以在本地检查它,以识别相关的元数据。

如果你想显式地从 PyPI 中选择一个包,你可以使用 --source 选项以及 add 命令,如下所示。

poetry add --source pypi httpx@^0.22.0

这将在你的 pyproject.toml 文件中生成以下配置片段。

httpx = {version = "^0.22.0", source = "pypi"}
警告
如果项目中的任何源都使用 priority = "default" 进行配置,则隐式 pypi 源将被禁用,不会用于任何包。

简单 API 存储库 #

Poetry 可以从实现简单存储库 API 的公共或私有自定义存储库中获取和安装包依赖项,如 PEP 503 中所述。

警告
当使用分发没有在文件 URL 中提供文件校验和的大型轮子的源时,Poetry 将至少下载一次每个候选轮子以生成校验和。当从该源添加包时,这可能表现为较长的依赖项解析时间。

这些包源可以通过以下命令在你的项目中进行配置。

poetry source add testpypi https://test.pypi.org/simple/
注意
请注意尾部的 /simple/。在配置 PEP 503 兼容的包源时,这一点很重要。

除了 PEP 503 之外,Poetry 还可以处理实现 PEP 658在 1.2.0 中引入)的简单 API 存储库。这有助于减少从这些源获取的包的依赖项解析时间,因为 Poetry 可以避免必须下载每个候选分发,以确定相关的元数据。

注意

为什么 Poetry 坚持在元数据不可用时下载所有平台的所有候选分发?

这源于 Poetry 的锁定文件是平台无关的。这意味着,为了解析项目的依赖项,Poetry 需要所有平台特定分发的元数据。当这些元数据不容易获得时,下载分发并在本地检查它是唯一剩下的选择。

在 1.2.0 中引入

一些项目选择通过部分遵循 PEP 503 中的包页结构的单页链接源发布其二进制分发。

这些包源可以通过以下命令在你的项目中进行配置。

poetry source add jax https://storage.googleapis.com/jax-releases/jax_releases.html
注意
关于简单 API 存储库中描述的较慢解析时间的全部注意事项也适用于此。

可发布的存储库 #

包源 不同,Poetry 将你发布包的存储库视为用户特定配置,而不是项目特定配置。目前,Poetry 仅在发布你的项目时支持 传统上传 API

这些是使用 config 命令在 repositories 键下配置的。

poetry config repositories.testpypi https://test.pypi.org/legacy/
注意
传统上传 API URL 通常与存储库为简单 API 提供的 URL 不同。你会注意到,在 Test PyPI 的示例中,主机 (test.pypi.org) 以及路径 (/legacy) 都与它的简单 API (https://test.pypi.org/simple) 不同。

配置凭据 #

如果你想为特定存储库存储你的凭据,你可以轻松地做到这一点

poetry config http-basic.foo <username> <password>

如果你没有指定密码,系统将提示你输入密码。

注意

要发布到 PyPI,你可以为名为 pypi 的存储库设置你的凭据。

请注意,建议在将软件包上传到 PyPI 时使用 API 令牌。创建新令牌后,您可以告诉 Poetry 使用它。

poetry config pypi-token.pypi <my-token>

如果您已将 testpypi 配置为 可发布的存储库,则可以使用以下方法设置令牌。

poetry config pypi-token.testpypi <your-token>

如果您仍然想使用用户名和密码,可以使用以下对 config 的调用。

poetry config http-basic.pypi <username> <password>

您也可以在使用 publish 命令时,使用 --username--password 选项指定用户名和密码。

如果系统密钥环可用且受支持,密码将存储到密钥环中并从密钥环中检索。在上面的示例中,凭据将使用名称 poetry-repository-pypi 存储。如果访问密钥环失败或不受支持,这将回退到将密码写入 auth.toml 文件以及用户名。

密钥环支持使用 keyring 库 启用。有关支持的后端的更多信息,请参阅 库文档

如果您不想使用密钥环,您可以告诉 Poetry 禁用它并将凭据存储在纯文本配置文件中。

poetry config keyring.enabled false
注意
Poetry 将回退到 Pip 样式的密钥环使用,以便像 Microsoft 的 artifacts-keyring 这样的后端有机会检索有效的凭据。它需要正确安装到 Poetry 的虚拟环境中,最好通过安装插件来完成。

或者,您可以使用环境变量来提供凭据。

export POETRY_PYPI_TOKEN_FOO=my-token
export POETRY_HTTP_BASIC_FOO_USERNAME=<username>
export POETRY_HTTP_BASIC_FOO_PASSWORD=<password>

其中 FOO 是存储库名称的大写形式(例如 PYPI)。有关如何使用环境变量配置 Poetry 的更多信息,请参阅 使用环境变量

如果您的密码以连字符开头(例如,在 CI 环境中随机生成的令牌),它将被解析为命令行选项而不是密码。您可以通过添加双连字符来防止这种情况,以防止任何后续参数被解析为选项。

poetry config -- http-basic.pypi myUsername -myPasswordStartingWithDash

证书 #

自定义证书颁发机构和双向 TLS 身份验证 #

Poetry 支持由自定义证书颁发机构保护的存储库,以及那些需要基于证书的客户端身份验证的存储库。以下将配置“foo”存储库以使用自定义证书颁发机构验证存储库的证书,并使用客户端证书(请注意,这些配置变量不需要同时设置)。

poetry config certificates.foo.cert /path/to/ca.pem
poetry config certificates.foo.client-cert /path/to/client.pem
注意

如果需要跳过证书验证,则可以将 certificates.<repository>.cert 的值设置为 false。这对于使用自签名证书的软件包源的情况很有用。

poetry config certificates.foo.cert false
警告
不建议禁用证书验证,因为它不符合安全最佳实践。

缓存 #

Poetry 为软件包源使用多个缓存,以改善用户体验并避免重复的网络请求。

第一级缓存是基于 Cache-Control 标头的缓存,用于几乎所有 HTTP 请求。

此外,每个 HTTP 支持的软件包源都会缓存与软件包关联的元数据,一旦它被获取或生成。此外,下载的文件(软件包分发)也会被缓存。

调试问题 #

如果您遇到软件包源问题,您可以采取的最简单的步骤之一是在使用 --no-cache 标志的情况下重新运行您的命令。

poetry --no-cache add pycowsay

如果这解决了您的问题,您可以考虑使用 cache 命令清除您的缓存。

或者,您也可以考虑启用非常详细的日志记录 -vvv 以及 --no-cache,以查看日志中正在进行的网络请求。