3.5 包索引
7 分钟阅读
3.5 包索引
默认情况下,uv 使用 Python 包索引(PyPI)进行依赖解析和包安装。不过,可以通过 [[tool.uv.index]] 配置选项(以及对应的命令行选项 --index)把 uv 配置为使用其他包索引,包括私有索引。
定义索引
要在解析依赖时包含额外的索引,请向 pyproject.toml 添加一个 [[tool.uv.index]] 条目:
| |
索引按定义顺序排定优先级,也就是说配置文件中列出的第一个索引是解析依赖时最先查询的索引;通过命令行提供的索引优先于配置文件中的索引。
默认情况下,uv 把 Python 包索引(PyPI)作为“默认”索引,即当某个包在任何其他索引上都找不到时使用的索引。要从索引列表中排除 PyPI,请在另一个索引条目上设置 default = true(或使用 --default-index 命令行选项):
| |
无论默认索引在索引列表中的位置如何,它始终被视为最低优先级。
索引名只能包含字母数字字符、短横线、下划线和句点,且必须是有效的 ASCII。
在命令行(用 --index 或 --default-index)或通过环境变量(UV_INDEX 或 UV_DEFAULT_INDEX)提供索引时,请使用它的 URL、已配置的名称,或 <name>=<url> 语法:
| |
使用 --preview-features index-by-name 时,已配置的索引名优先于匹配的路径。
把包固定到索引
可以通过在包的 tool.uv.sources 条目中指定索引,把包固定到特定索引。例如,要确保 torch 始终从 pytorch 索引安装,请在 pyproject.toml 中加入:
| |
同样,要按平台从不同索引拉取,可以提供用环境标记区分的来源列表:
| |
可以把索引标记为 explicit = true,以防止包从该索引安装,除非它们被显式固定到它。例如,要确保 torch 从 pytorch 索引安装,而其他所有包从 PyPI 安装,请在 pyproject.toml 中加入:
| |
通过 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 的行为,但它会让用户面临“依赖混淆”攻击的风险。
身份验证
大多数私有包索引都要求身份验证才能访问包,通常通过用户名和密码(或访问令牌)。
提示
关于使用特定私有索引提供程序进行身份验证,请参阅专门的指南:Azure Artifacts、Google Artifact Registry、AWS CodeArtifact 和 JFrog Artifactory。
直接提供凭据
凭据可以通过环境变量直接提供,也可以嵌入 URL 中。
例如,给定一个需要用户名(public)和密码(koala)的索引 internal-proxy,在 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 会主动搜索凭据,并在找不到凭据时报错。
忽略错误码
使用 first-index 策略时,如果遇到 HTTP 401 Unauthorized 或 HTTP 403 Forbidden 状态码,uv 会停止跨索引搜索。唯一的例外是搜索 pytorch 索引时 uv 会忽略 403(因为该索引在包不存在时返回 403)。
默认情况下,如果从索引获取分发包元数据或归档时遇到 HTTP 错误,uv 也会停止解析。忽略该错误会把受影响的包版本标记为不可用,让解析器尝试其他版本。
要配置对某个索引忽略哪些错误码,请使用 ignore-error-codes 设置。例如,对私有索引忽略 403(但不忽略 401):
| |
当遇到 404 Not Found 时,uv 始终会继续跨索引搜索。这无法覆盖。
禁用身份验证
为防止凭据泄漏,可以为索引禁用身份验证:
| |
当 authenticate 设为 never 时,uv 永远不会为给定索引搜索凭据,并且在直接提供凭据时会报错。
自定义缓存控制头
默认情况下,uv 会遵循索引提供的缓存控制头。例如,PyPI 以 max-age=600 头提供包元数据,从而允许 uv 缓存包元数据 10 分钟;wheel 和源码分发则带 max-age=365000000, immutable 头,从而允许 uv 无限期缓存产物。
要覆盖索引的缓存控制头,请使用 cache-control 设置:
| |
cache-control 设置接受一个带两个可选键的对象:
api:控制 Simple API 请求(包元数据)的缓存。files:控制产物下载(wheel 和源码分发)的缓存。
这些键的值是遵循 HTTP Cache-Control 语法的字符串。例如,要强制 uv 始终重新校验包元数据,请设置 api = "no-cache":
| |
该设置最常用于覆盖私有索引的默认缓存控制头 —— 这些索引往往会(常常是无意地)禁用缓存。我们通常建议采用 PyPI 的缓存头做法,即设置 api = "max-age=600" 和 files = "max-age=365000000, immutable"。
要求哈希算法
当索引为一个分发公布多个哈希时,uv 会选择单个哈希记录到锁文件中。要为由某个索引解析出的分发生成特定算法,请使用 hash-algorithm 设置:
| |
如果某个已锁定的分发未公布所要求的算法,uv 会失败,而不是回退到其他哈希算法。
为索引配置 exclude-newer
如果你使用 exclude-newer,可以为特定索引配置不同的截止时间:
| |
索引专属的值只影响由该索引提供的包。按包配置的 exclude-newer-package 覆盖仍然优先。
如果某个索引不提供 upload-time 元数据,你可以完全禁用该索引的截止时间:
| |
“扁平”索引
默认情况下,[[tool.uv.index]] 条目被假定为实现 PEP 503 Simple Repository API 的 PyPI 风格仓库。不过 uv 也支持“扁平”索引,即包含 wheel 和源码分发扁平列表的本地目录或 HTML 页面。在 pip 中,这类索引通过 --find-links 选项指定。
要在 pyproject.toml 中定义扁平索引,请使用 format = "flat" 选项:
| |
扁平索引支持与 Simple Repository 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。