包索引
默认情况下,uv 使用 Python 包索引(PyPI) 来解析依赖项并安装包。不过,可以通过 [[tool.uv.index]]
配置选项(以及对应的命令行选项 --index
)将 uv 配置为使用其他包索引,包括私有索引。
定义索引
要在解析依赖项时包含额外的索引,需在 pyproject.toml
中添加 [[tool.uv.index]]
条目:
[[tool.uv.index]]
# 索引的可选名称。
name = "pytorch"
# 索引的必填 URL。
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>
语法包含,如下所示:
# 在命令行中。
$ uv lock --index pytorch=https://download.pytorch.org/whl/cpu
# 通过环境变量。
$ 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
,以防止从该索引安装包,除非明确将包固定到该索引。例如,为确保 torch
从 pytorch
索引安装,但其他所有包都从 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 的行为,但它使用户面临 “依赖混淆” 攻击的风险。
身份验证
大多数私有软件包索引需要进行身份验证才能访问软件包,通常是通过用户名和密码(或访问令牌)。
Tip
有关使用特定私有索引提供商(例如 AWS、Azure 或 GCP)进行身份验证的详细信息,请参阅 替代索引指南。
直接提供凭证
可以通过环境变量直接提供凭证,也可以将其嵌入到 URL 中。
例如,假设有一个名为 internal-proxy
的索引,需要用户名(public
)和密码(koala
),在 pyproject.toml
中定义该索引(不包含凭证):
从这里开始,你可以设置 UV_INDEX_INTERNAL_PROXY_USERNAME
和 UV_INDEX_INTERNAL_PROXY_PASSWORD
环境变量,其中 INTERNAL_PROXY
是索引名称的大写形式,非字母数字字符将替换为下划线:
通过环境变量提供凭证,可以避免在纯文本的 pyproject.toml
文件中存储敏感信息。
或者,也可以将凭证直接嵌入到索引定义中:
出于安全考虑,凭证永远不会存储在 uv.lock
文件中;因此,uv 在安装时必须能够访问经过身份验证的 URL。
使用凭证提供程序
除了直接提供凭证外,uv 还支持从 netrc 和 keyring 中查找凭证。有关设置特定凭证提供程序的详细信息,请参阅HTTP 身份验证文档。
默认情况下,uv 会在查询提供程序之前尝试进行未经身份验证的请求。如果请求失败,uv 将搜索凭证。如果找到凭证,将尝试进行身份验证的请求。
注意
如果设置了用户名,uv 将在发出未经身份验证的请求之前搜索凭证。
一些索引(例如 GitLab)会将未经身份验证的请求转发到公共索引,如 PyPI,这意味着 uv 将不会搜索凭证。可以使用 authenticate
设置针对每个索引更改此行为。例如,要始终搜索凭证:
当 authenticate
设置为 always
时,uv 将积极搜索凭证,如果找不到凭证则会报错。
在跨索引搜索时忽略错误代码
使用首个索引策略时,如果遇到 HTTP 401 未经授权或 HTTP 403 禁止访问状态码,uv 将停止跨索引搜索。唯一的例外是,uv 在搜索 pytorch
索引时将忽略 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 永远不会为指定索引查找凭证,并且如果直接提供凭证则会报错。
“扁平”索引
默认情况下,[[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
。