跳到内容

包索引

默认情况下,uv 使用 Python 包索引 (PyPI) 进行依赖项解析和包安装。但是,uv 可以配置为使用其他包索引,包括私有索引,通过 [[tool.uv.index]] 配置选项(以及 --index,类似的命令行选项)。

定义索引

要在解析依赖项时包含其他索引,请将 [[tool.uv.index]] 条目添加到您的 pyproject.toml

[[tool.uv.index]]
# Optional name for the index.
name = "pytorch"
# Required URL for the index.
url = "https://download.pytorch.org/whl/cpu"

索引按照定义的顺序进行优先级排序,配置文件中列出的第一个索引是在解析依赖项时首先查询的索引,通过命令行提供的索引优先于配置文件中的索引。

默认情况下,uv 包括 Python 包索引 (PyPI) 作为“默认”索引,即当在任何其他索引上都找不到包时使用的索引。要从索引列表中排除 PyPI,请在另一个索引条目上设置 default = true(或使用 --default-index 命令行选项)

[[tool.uv.index]]
name = "pytorch"
url = "https://download.pytorch.org/whl/cpu"
default = true

无论默认索引在索引列表中的位置如何,它始终被视为最低优先级。

索引名称只能包含字母数字字符、破折号、下划线和句点,并且必须是有效的 ASCII。

在命令行 (使用 --index--default-index) 或通过环境变量 (UV_INDEXUV_DEFAULT_INDEX) 提供索引时,名称是可选的,但可以使用 <name>=<url> 语法包含,例如

# On the command line.
$ uv lock --index pytorch=https://download.pytorch.org/whl/cpu
# Via an environment variable.
$ UV_INDEX=pytorch=https://download.pytorch.org/whl/cpu uv lock

将包固定到索引

通过在其 tool.uv.sources 条目中指定索引,可以将包固定到特定索引。例如,要确保 torch 始终pytorch 索引安装,请将以下内容添加到您的 pyproject.toml

[tool.uv.sources]
torch = { index = "pytorch" }

[[tool.uv.index]]
name = "pytorch"
url = "https://download.pytorch.org/whl/cpu"

同样,要根据平台从不同的索引中提取,您可以提供由环境标记消除歧义的源列表

pyproject.toml
[project]
dependencies = ["torch"]

[tool.uv.sources]
torch = [
  { index = "pytorch-cu118", marker = "sys_platform == 'darwin'"},
  { index = "pytorch-cu124", marker = "sys_platform != 'darwin'"},
]

[[tool.uv.index]]
name = "pytorch-cu118"
url = "https://download.pytorch.org/whl/cu118"

[[tool.uv.index]]
name = "pytorch-cu124"
url = "https://download.pytorch.org/whl/cu124"

可以将索引标记为 explicit = true,以防止从该索引安装软件包,除非显式地将其固定到该索引。例如,要确保从 pytorch 索引安装 torch,但从 PyPI 安装所有其他软件包,请将以下内容添加到您的 pyproject.toml

[tool.uv.sources]
torch = { index = "pytorch" }

[[tool.uv.index]]
name = "pytorch"
url = "https://download.pytorch.org/whl/cpu"
explicit = true

通过 tool.uv.sources 引用的命名索引必须在项目的 pyproject.toml 文件中定义;通过命令行、环境变量或用户级配置提供的索引将无法识别。

如果一个索引被标记为 default = trueexplicit = true,它将被视为一个显式索引(即,只能通过 tool.uv.sources 使用),同时也会删除 PyPI 作为默认索引。

跨多个索引搜索

默认情况下,uv 将在给定软件包可用的第一个索引上停止,并将解析限制为该第一个索引上存在的那些(first-index)。

例如,如果通过 [[tool.uv.index]] 指定了内部索引,则 uv 的行为是,如果软件包存在于该内部索引上,则它将始终 从该内部索引安装,而不是从 PyPI 安装。 这样做的目的是为了防止“依赖项混淆”攻击,在这种攻击中,攻击者在 PyPI 上发布一个恶意软件包,该软件包与内部软件包的名称相同,从而导致安装恶意软件包而不是内部软件包。例如,请参阅 2022 年 12 月的 torchtriton 攻击

要选择加入替代索引行为,请使用 --index-strategy 命令行选项或 UV_INDEX_STRATEGY 环境变量,它支持以下值

  • first-index (默认): 在所有索引中搜索每个软件包,将候选版本限制为第一个包含该软件包的索引中存在的版本。
  • unsafe-first-match: 在所有索引中搜索每个软件包,但优先选择具有兼容版本的第一个索引,即使其他索引上有更新的版本可用。
  • unsafe-best-match: 在所有索引中搜索每个软件包,并从候选版本的组合集中选择最佳版本。

虽然 unsafe-best-match 最接近 pip 的行为,但它使用户面临“依赖项混淆”攻击的风险。

身份验证

大多数私有软件包索引都需要身份验证才能访问软件包,通常通过用户名和密码(或访问令牌)。

提示

有关使用特定私有索引提供程序(例如,来自 AWS、Azure 或 GCP)进行身份验证的详细信息,请参阅 替代索引指南

直接提供凭据

可以通过环境变量直接提供凭据,也可以将它们嵌入到 URL 中。

例如,给定一个名为 internal-proxy 的索引,该索引需要用户名 (public) 和密码 (koala),请在您的 pyproject.toml 中定义该索引(不含凭据)

[[tool.uv.index]]
name = "internal-proxy"
url = "https://example.com/simple"

从那里,您可以设置 UV_INDEX_INTERNAL_PROXY_USERNAMEUV_INDEX_INTERNAL_PROXY_PASSWORD 环境变量,其中 INTERNAL_PROXY 是索引名称的大写版本,非字母数字字符替换为下划线

export UV_INDEX_INTERNAL_PROXY_USERNAME=public
export UV_INDEX_INTERNAL_PROXY_PASSWORD=koala

通过环境变量提供凭据,您可以避免将敏感信息存储在纯文本 pyproject.toml 文件中。

或者,可以将凭据直接嵌入到索引定义中

[[tool.uv.index]]
name = "internal"
url = "https://public:[email protected]/simple"

出于安全目的,凭据永远 不会存储在 uv.lock 文件中;因此,uv 必须 在安装时访问经过身份验证的 URL。

使用凭据提供程序

除了直接提供凭据之外,uv 还支持从 netrc 和密钥环中发现凭据。 有关设置特定凭据提供程序的详细信息,请参阅 HTTP 身份验证 文档。

默认情况下,uv 会在查询提供程序之前尝试未经身份验证的请求。如果请求失败,uv 将搜索凭据。如果找到凭据,将尝试经过身份验证的请求。

注意

如果设置了用户名,uv 将在发出未经身份验证的请求之前搜索凭据。

某些索引(例如,GitLab)会将未经身份验证的请求转发到公共索引,例如 PyPI — 这意味着 uv 将不会搜索凭据。可以使用 authenticate 设置按索引更改此行为。例如,始终搜索凭据

[[tool.uv.index]]
name = "example"
url = "https://example.com/simple"
authenticate = "always"

authenticate 设置为 always 时,uv 将急切地搜索凭据,如果找不到凭据,则会出错。

跨索引搜索时忽略错误代码

使用 first-index 策略时,如果遇到 HTTP 401 Unauthorized 或 HTTP 403 Forbidden 状态代码,uv 将停止跨索引搜索。唯一的例外是,在搜索 pytorch 索引时,uv 将忽略 403(因为当软件包不存在时,此索引会返回 403)。

要配置为索引忽略哪些错误代码,请使用 ignored-error-codes 设置。例如,要忽略私有索引的 403(而不是 401)

[[tool.uv.index]]
name = "private-index"
url = "https://private-index.com/simple"
authenticate = "always"
ignore-error-codes = [403]

当 uv 遇到 404 Not Found 时,它将始终继续跨索引搜索。这无法被覆盖。

禁用身份验证

为防止泄露凭据,可以禁用索引的身份验证

[[tool.uv.index]]
name = "example"
url = "https://example.com/simple"
authenticate = "never"

authenticate 设置为 never 时,uv 将永远不会搜索给定索引的凭据,并且如果直接提供凭据,则会出错。

自定义缓存控制标头

默认情况下,uv 将遵守索引提供的缓存控制标头。例如,PyPI 提供带有 max-age=600 标头的软件包元数据,从而允许 uv 缓存软件包元数据 10 分钟;以及带有 max-age=365000000, immutable 标头的 wheel 和源分发,从而允许 uv 无限期地缓存工件。

要覆盖索引的缓存控制标头,请使用 cache-control 设置

[[tool.uv.index]]
name = "example"
url = "https://example.com/simple"
cache-control = { api = "max-age=600", files = "max-age=365000000, immutable" }

cache-control 设置接受一个带有两个可选键的对象

  • api:控制简单 API 请求(软件包元数据)的缓存。
  • files:控制工件下载(wheel 和源分发)的缓存。

这些键的值是遵循 HTTP Cache-Control 语法的字符串。例如,要强制 uv 始终重新验证软件包元数据,请设置 api = "no-cache"

[[tool.uv.index]]
name = "example"
url = "https://example.com/simple"
cache-control = { api = "no-cache" }

此设置最常用于覆盖私有索引的默认缓存控制标头,这些索引会以其他方式禁用缓存,通常是无意的。我们通常建议遵循 PyPI 的缓存标头方法,即设置 api = "max-age=600"files = "max-age=365000000, immutable"

“扁平”索引

默认情况下,[[tool.uv.index]] 条目被假定为实现 PEP 503 简单存储库 API 的 PyPI 样式注册表。但是,uv 还支持“扁平”索引,它们是包含 wheel 和源分发的扁平列表的本地目录或 HTML 页面。在 pip 中,此类索引使用 --find-links 选项指定。

要在您的 pyproject.toml 中定义一个扁平索引,请使用 format = "flat" 选项

[[tool.uv.index]]
name = "example"
url = "/path/to/directory"
format = "flat"

扁平索引支持与简单存储库 API 索引相同的功能集(例如,explicit = true);您还可以使用 tool.uv.sources 将软件包固定到扁平索引。

--index-url--extra-index-url

除了 [[tool.uv.index]] 配置选项之外,uv 还支持 pip 样式的 --index-url--extra-index-url 命令行选项以实现兼容性,其中 --index-url 定义默认索引,--extra-index-url 定义其他索引。

这些选项可以与 [[tool.uv.index]] 配置选项结合使用,并遵循相同的优先级规则

  • 默认索引始终被视为最低优先级,无论是通过旧版 --index-url 参数、推荐的 --default-index 参数还是带有 default = true[[tool.uv.index]] 条目定义。
  • 索引按照定义的顺序进行咨询,无论是通过旧版 --extra-index-url 参数、推荐的 --index 参数还是 [[tool.uv.index]] 条目。

实际上,--index-url--extra-index-url 可以被认为是未命名的 [[tool.uv.index]] 条目,其中前者启用了 default = true。 在这种情况下,--index-url 映射到 --default-index--extra-index-url 映射到 --index