包索引
默认情况下,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
命令行选项)
无论默认索引在索引列表中的位置如何,它始终被视为最低优先级。
索引名称只能包含字母数字字符、破折号、下划线和句点,并且必须是有效的 ASCII。
在命令行 (使用 --index
或 --default-index
) 或通过环境变量 (UV_INDEX
或 UV_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"
同样,要根据平台从不同的索引中提取,您可以提供由环境标记消除歧义的源列表
[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 = true
和 explicit = 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
中定义该索引(不含凭据)
从那里,您可以设置 UV_INDEX_INTERNAL_PROXY_USERNAME
和 UV_INDEX_INTERNAL_PROXY_PASSWORD
环境变量,其中 INTERNAL_PROXY
是索引名称的大写版本,非字母数字字符替换为下划线
通过环境变量提供凭据,您可以避免将敏感信息存储在纯文本 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
设置按索引更改此行为。例如,始终搜索凭据
当 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
时,它将始终继续跨索引搜索。这无法被覆盖。
禁用身份验证
为防止泄露凭据,可以禁用索引的身份验证
当 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"
选项
扁平索引支持与简单存储库 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
。