Conda的前世今生

在介绍pixi之前,有必要先聊聊Conda。实际上Conda最早诞生于2012年,晚于pip和venv,为什么在已经存在pip和venv的情况下,还要推出一个看似重复的包管理工具呢?

将时间倒回2012年,python的包管理面临着一个巨大的问题。彼时,很多科学计算库(如 NumPy, SciPy, Pandas)底层都是用 C、C++ 或 Fortran 编写的,而 pip 主要安装的是源码包(sdist)。这意味着当你执行pip install numpy时,你的电脑必须装有对应的编译器、动态链接库和复杂的数学库(如 MKL 或 OpenBLAS)。如果环境不匹配,安装就会报错。这是一个让人头疼的事情(尤其是那些编程基础本就不扎实的科学家们)。

当时 Anaconda 的创始人 Travis Oliphant 意识到,科学计算的用户(物理学家、生物学家、金融分析师)不应该把时间花在解决 gcc 编译器报错上。因此,Conda出现了,它直接分发预编译好的二进制文件。这就意味着用户不需要在本地编译,直接下载解压就能用。由于不需要处理那些烦人的依赖,这对很多那些科学家来说简直是救命稻草。而将所有这些库以及非python编写的依赖库打包在一起的巨大的库,就是 Anaconda Distribution。如今,它是目前全球最流行的科学计算平台,本质上是将 Python、Conda 包管理器以及一大堆常用的科学计算库打包在一起的软件发行版。

不过在最初,Anaconda Distribution只是一个将所有软件包放在一起的大杂烩,在后续的更新中,人们意识到需要一个类似于 pip 的命令来管理这些依赖库,比如添加、更新和删除依赖,于是,conda命令行诞生了。他们维护的那个软件包仓库,在当时叫做default

在一段时间以来,他们维护着官方的 defaults ,这是一个经过严格测试的软件包仓库,兼容性极好。但问题也随之而来:科学计算的世界太大了。除了 NumPyPandas 这些通用的,还有成千上万个小众领域的库(比如天文学的 Astropy、地理信息的 GDAL、生物信息学的Biopython)。这对于一家商业公司(当时甚至只是个创业公司)来说,根本没有人力去打包、编译、测试全世界所有的科学软件。而且,Conda 包是二进制文件,需要针对 Windows、Linux、macOS 分别编译,工作量是 PyPI 的数倍。

为了解决这个问题,Anaconda开放了 Channel 机制。 他们推出了 Anaconda.org(最初叫 Binstar.org),允许用户创建自己的 Channel。如果你需要的包官方不提供,那么你可以自己打包上传到你的个人频道,别人只要添加你的 URL 就能下载。

将权限下放给用户,解决了官方维护成本的问题,但是随着个人 Channel 的开放,又带来了过于混乱的问题。很快,大家就发现,如果要装 tensorflow,在搜索时可能会发现:

  • google/tensorflow
  • zhang3/tensorflow
  • alice/tensorflow

如此多的tensorflow,你敢用吗?这些包是基于什么环境编译的?有没有植入恶意代码?彼此兼容吗?一群核心开发者意识到,不能让成千上万个个人频道各自为战。于是他们建立了一个社区驱动的超级频道 —— conda-forge。它引入了自动化的 CI/CD 流水线。任何人都可以在 GitHub 上提交 Recipe,由CI自动构建,并由社区审核。它解决了信任和标准化的问题,成为了现如今的事实标准。

而对于那些生物信息学的软件。很多底层工具是用 Perl、C++ 甚至 Fortran 写的老古董,而且依赖关系极其复杂(不仅仅依赖 Python,还依赖系统级的库)。这些软件对于做金融或做 Web 开发的人来说完全没有用,拖慢搜索速度。而且,生物软件的版本更新逻辑和通用软件完全不同。因此,Bioconda Channel 诞生了。 这是一群生物学家建立的。他们把所有生物相关的软件(超过 7000 个)都放在这个频道里。通过 Channel,不同领域的人可以在自己的圈子里维护自己的生态,互不干扰。

pixi:新时代的包管理方案

既然 Conda 生态已经如此成熟,为什么还需要 pixi?

简单来说,pixi 是一个基于 Rust 编写(底层使用 rattler 库)、强调完全可重现性和极高性能的现代化包管理器。它不仅完全兼容 Conda 庞大的 conda-forge 生态,还通过内置的 uv 库实现了对 PyPI 的“一等公民”级支持。

相比于传统的 Conda 客户端,pixi 的核心优势在于:

  1. 快到极致:依赖解析速度比传统 conda 快几个数量级。
  2. 声明式配置:不再依赖一系列手动输入的命令行指令,所有配置都记录在一个 pixi.toml 中。
  3. 强制锁文件:生成 pixi.lock 确保跨平台、跨机器的安装结果 100% 一致。
  4. 无需激活:直接运行 pixi run 即可,不再需要繁琐的 conda activate

本文章介绍pixi的基本用法和最佳实践,并不作为百科全书使用,要想了解更多,强烈建议去查看官方文档


快速上手

对于 Python 项目,pixi 推荐直接使用 pyproject.toml 作为配置文件。这不仅符合 Python 社区的标准,还能让你在同一个文件中管理构建系统、项目元数据以及 pixi 专有的环境配置。

1. 安装 pixi

在 macOS 或 Linux 上,使用官方脚本进行一键安装:

1
curl -fsSL https://pixi.sh/install.sh | sh

安装脚本会将 ~/.pixi/bin 添加到 PATH。安装完成后,重启终端以使配置生效。

要更新pixi,可以使用如下命令:

1
pixi self-update

2. 初始化项目(pyproject.toml 模式)

进入你的项目目录,使用 --format pyproject 参数初始化:

1
2
pixi init test1 --format pyproject
cd test1

如图,这将创建一个具有以下结构的项目目录:

其中,pyproject.toml 内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[project]
authors = [{name = "hiltay", email = "yyyzlyh@gmail.com"}]
dependencies = []
name = "test1"
requires-python = ">= 3.11"
version = "0.1.0"

[build-system]
build-backend = "hatchling.build"
requires = ["hatchling"]

[tool.pixi.workspace]
channels = ["conda-forge"]
platforms = ["linux-64"]

[tool.pixi.pypi-dependencies]
test1 = { path = ".", editable = true }

[tool.pixi.tasks]

Pixi 中使用 pyproject.toml 作为清单文件。这样用户只需一个文件即可管理所有配置。 pyproject.toml 文件是 Python 项目的标准配置。我们不建议将 pyproject.toml 文件用于 Python 项目以外的任何用途, pixi.toml 更适合其他类型的项目。

我们来看看里面分别添加了什么:

1
2
3
4
5
# pixi 入口
[tool.pixi.workspace]
channels = ["conda-forge"]
# 默认是pixi所处机器的平台,如果是macos则这里应该是osx-arm64
platforms = ["linux-64"]

channelsplatforms 被添加到 [tool.pixi.workspace] 部分。conda-forge 作为默认的Channel。关键字 platforms 决定了工作区支持哪些平台,如果你希望在macos和linux平台使用,可以改为platforms = ["linux-64", "osx-arm64"]

1
2
3
# Editable installs
[tool.pixi.pypi-dependencies]
test1 = { path = ".", editable = true }

test1 包本身被添加为 editable 依赖项。这意味着该包以可编辑模式安装,因此你可以对包进行更改并在环境中看到更改的反映,而无需重新安装它。

1
2
3
[build-system]
build-backend = "hatchling.build"
requires = ["hatchling"]

pyproject.toml 文件通常包含一个 [build-system] 部分。如果该项目被添加为 PyPI 路径依赖项,Pixi 将使用此部分来构建和安装该项目。pixi init --format pyproject 默认使用 hatchling 作为构建后端,你可以在Choosing a build backend查看更多内容。

pixi 会自动将 requires-python 映射为 Python 依赖,pixi 可以识别该字段,并自动将 Python 版本添加到依赖项中。

3. 添加依赖(Conda 与 PyPI 混合)

我们的项目通常依赖于其他软件包。pixi 遵循 “Conda 优先” 策略:先解析 Conda 依赖,再处理 PyPI 依赖。

1
pixi add numpy

该命令会自动添加conda依赖,并写入 [tool.pixi.dependencies]

1
2
[tool.pixi.dependencies]
numpy = ">=2.4.2,<3"

有些软件包在 conda-forge 上不可用,但在 PyPI 上却有发布。使用--pypi参数添加 PyPI 依赖:

1
pixi add black --pypi

此时的依赖会自动添加到 [project.dependencies]

1
2
[project]
dependencies = ["black>=26.1.0,<27"]

并且在执行后,pixi 会更新 pyproject.toml 并同步生成 pixi.lock 文件。该锁文件记录了跨平台一致的精确依赖版本。

4.修改cache路径

Pixi 会将所有先前下载的软件包缓存到一个缓存文件夹中。该缓存文件夹在所有 Pixi 工作区和全局安装的工具之间共享。

通常情况下默认的缓存路径如下:

  • Linux: $XDG_CACHE_HOME/rattler$HOME/.cache/rattler
  • macOS: $HOME/Library/Caches/rattler
  • Windows: %LOCALAPPDATA%\rattler

可通过设置 PIXI_CACHE_DIRRATTLER_CACHE_DIR 环境变量来配置此位置。比如:

1
export PIXI_CACHE_DIR=/somewhere/a/b/tmp/pixi_cache

使用pixi info可以查看到有关缓存位置的信息:

1
Cache dir: /somewhere/a/b/tmp/pixi_cache

在实践中,如果$HOME存储空间有限,建议修改PIXI_CACHE_DIR至大容量存储位置。

5. 安装环境

当别人使用pixi管理项目并向你共享时,你可以通过pixi install来获得相同的依赖包。

运行该命令,工作区根目录会新增一个名为 .pixi 的目录。该环境是一个 Conda 环境,其中已安装了所有 Conda 和 PyPI 依赖项。

环境始终由 pixi.lock 文件生成,而 pixi.lock 文件又由 pyproject.toml 文件生成。该文件包含了跨平台环境中已安装的依赖项的确切版本。

6. 运行代码

在 pixi 中,你不需要手动激活环境。通过 pixi run 执行命令时,pixi 会自动确保环境处于最新状态。

直接运行 Python 命令:

1
pixi run python -c "import rich; rich.print('[bold magenta]Hello Pixi![/bold magenta]')"

如果需要交互式 Shell,可以使用:

1
2
3
4
pixi shell
# 此时已进入激活的隔离环境
python --version
exit

5. 查看环境状态

1
2
3
4
5
# 列出当前环境的所有包及其来源(Conda 或 PyPI)
pixi list

# 查看项目配置和虚拟包(Virtual Packages)信息
pixi info

最佳实践

1. 使用 [tool.uv.sources]

因为 pixi 使用 uv 来构建其 pypi-dependencies ,所以可以使用 tool.uv.sources 部分来指定从主 pixi 清单引用的任何 pypi 依赖项的来源。

首先创建一个新的项目:

1
2
3
pixi init example --format pyproject
pixi init a --format pyproject
pixi init b --format pyproject

我们希望example作为主项目,引用a的依赖项,而a引用b的依赖项,我们希望引用结构如下所示:

1
2
3
4
5
6
7
.
├── example
│ └── pyproject.toml (references a)
├── a
│ └── pyproject.toml (has a dependency on b)
└── b
└── pyproject.toml

具体来说,这在 examplepyproject.toml 文件中看起来是这样的:

1
2
3
[tool.pixi.pypi-dependencies]
example = { path = ".", editable = true }
a = { path = "../a" }

那么此时a中的 pyproject.toml 应该包含一个 [tool.uv.sources] 部分:

1
2
3
4
5
6
7
8
9
[project]
dependencies = ["httpx", "b"]
name = "a"
requires-python = ">= 3.11"

[tool.uv.sources]
httpx = { git = "https://github.com/encode/httpx", branch = "master" }
# Reference to b
b = { path = "../b" }

让我们检查一下:

1
2
3
4
cd example
pixi run python -c "import httpx; import black; print(httpx.__version__, black.__version__)"
# 或者使用`pixi list`查看依赖详情。
pixi list

需要注意的是,截至目前为止,主 pixi.tomlpyproject.toml 文件由 pixi 直接解析,而非由 uv 处理。这意味着你无法在主 pixi.tomlpyproject.toml 文件中使用 [tool.uv.sources] 部分。

想了解更多关于[tool.uv.sources]的内容,请参考uv文档

2. System Requirements

System Requirements用于告知 Pixi 安装和运行你的环境所需的系统规格。它们确保依赖项与你机器的操作系统和硬件相匹配。

这用于定义你的环境可以在哪些“类型的机器”上运行。比如:

1
2
3
4
5
[system-requirements]
linux = "4.18"
libc = { family = "glibc", version = "2.28" }
cuda = "12"
macos = "13.0"

这样就形成了一个可以在以下平台上运行的环境:

  • Linux 内核版本 4.18
  • GNU C 库 (glibc) 版本 2.28
  • CUDA 版本 12
  • macOS 版本 13.0

在依赖求解时,Pixi 会结合使用:

  • platforms 的默认要求
  • 通过 [system-requirements] 添加的任何自定义要求

System Requirements以虚拟包的形式添加。虚拟包是特殊的包(例如 __linux__cuda__glibc ),它们不包含任何文件。它们仅声明系统上可用的功能,求解器使用它们来过滤掉不兼容的包。

System Requirements并未指定最高或最低版本,而是指定了主机系统上可以安装的版本。依赖求解器会根据可用版本来判断系统是否满足要求。例如:

  • 一个软件包可能需要 __cuda >= 12 ,而系统可以有 12.1 或任何 12.6 版本。
  • 一个软件包可能需要 __cuda <= 12 ,而系统可以有 12.0.0 或任何 11 的版本。

大多数情况下,软件包会指定其所需的最低版本( >= )。因此,我们常说 system-requirements 定义了系统规范的最低版本。

2.1 使用cuda

要在环境中使用 CUDA,你必须在系统需求表中指定所需的 CUDA 版本。这可以确保 CUDA 被识别,并在必要时将其正确锁定到pixi.lock中。

1
2
[system-requirements]
cuda = "12"

system-requirements 这样写,是否等于强制指定 CUDA 运行时版本? 答案是不能。 system-requirements 字段用于根据主机的 NVIDIA 驱动程序 API 指定支持的 CUDA 版本。添加此字段可确保正确解析依赖于 __cuda >= {version} 的软件包。因此,这是在告诉 Pixi:CUDA 版本 12 可用,并且可以在解析过程中使用。

3. 安装Pytorch

我们大致有两种方式来安装pytorch。下面的toml清单均以pyproject.toml为例。

3.1 从Conda-forge安装

可以使用 conda-forge 安装 PyTorch。这些是由 conda-forge 社区维护的 PyTorch 构建版本。你可以直接使用 Nvidia 提供的软件包,以确保这些软件包能够协同工作。

1
2
3
4
5
6
7
8
9
10
11
12
[project]
name = "pytorch-conda-forge"

[tool.pixi.workspace]
channels = ["conda-forge"]
platforms = ["linux-64"]

[tool.pixi.system-requirements]
cuda = "12.0"

[tool.pixi.dependencies]
pytorch-gpu = "*"

这样默认安装的是符合要求的、且与环境中cuda版本相同的torch:

1
pixi list | grep cuda

要指定安装特定版本的 cuda 软件包,可以添加一条cuda-version依赖,其他软件包会在依赖解析过程中根据该依赖关系进行配置。cuda cuda-version 会限制 __cuda 虚拟软件包和 cudatoolkit 软件包的版本。这确保了正确安装 cudatoolkit 软件包版本,并正确解析依赖关系树。

1
2
3
[tool.pixi.dependencies]
pytorch-gpu = "*"
cuda-version = "12.6.*"
1
pixi list | grep cuda

3.2 从 PyPI 安装

由于 pixi 与 uv 集成,我们还可以从 PyPI 安装 PyTorch。但是有以下注意事项:

如果使用这种方法安装 torch 包,还应该从 PyPI 安装 torch 的依赖包。因此,如果 Conda 包依赖于 PyPI 包,则不要将 PyPI 包与 Conda 包混用。 原因在于pixi解析过程分为两步:首先解析 Conda 包,然后解析 PyPI 包。因此,如果我们要求某个 Conda 包依赖于某个 P​​yPI 包,则解析过程无法成功。

PyTorch 包通过自定义索引(index-url)提供,类似于 Conda Channel,由 PyTorch 团队维护。要从 PyTorch 索引安装 PyTorch,需要将索引添加到清单文件中。最好为每个依赖项都添加此操作,以强制使用该索引。

1
2
3
4
[tool.pixi.pypi-dependencies]
torch = { version = ">=2.7.1", index = "https://download.pytorch.org/whl/cu128" }
torchvision = { version = ">=0.22.1", index = "https://download.pytorch.org/whl/cu128" }
torchaudio = { version = ">=2.7.1", index = "https://download.pytorch.org/whl/cu128" }
1
pixi list | grep cuda

3.3 从 PyTorch 频道安装(不推荐)

由于 PyTorch 官方已停止运营其官方Channel,因此该方法不会更新到更高版本。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[project]
name = "pytorch-from-pytorch-channel"
requires-python = ">= 3.11"
version = "0.1.0"

[tool.pixi.workspace]
channels = ["nvidia", "pytorch"]
platforms = ["linux-64"]

[tool.pixi.feature.gpu.system-requirements]
cuda = "12.0"

[tool.pixi.dependencies]
pytorch = "*"

[tool.pixi.environments]
gpu = ["gpu"]

3.4 注意事项

  1. 同时使用 conda-forge 和旧版 pytorch Channel可能会导致冲突。请选择一个Channel并坚持使用它,以避免环境问题。对于新项目而言,建议使用conda-forge
  2. 如果从 PyPI 安装 PyTorch,所有依赖于 PyTorch 的软件包也必须来自 PyPI。在同一依赖链中混用 Conda 和 PyPI 软件包会导致冲突。
  3. 检查 Pixi 在你的机器上检测到的 CUDA 版本,请运行:pixi info,其中可以查看到:
    1
    2
    3
    Virtual packages: __unix=0=0
    : __glibc=2.35=0
    : __cuda=12.9=0
    如果缺少 __cuda ,可以使用 NVIDIA 工具验证系统的 CUDA 版本:
    1
    nvidia-smi
  4. 检查环境中安装的 CUDA 工具包版本:
    1
    pixi run nvcc --version

4. Environment(环境)和 Multi Environment (多环境)

4.1 环境

Environment(环境)其实就是一组安装在特定位置的文件,它在某种程度上模拟了全局系统安装。但它有两个非常关键的特点,区别于 Conda 或 venv,pixi环境默认存放在当前项目的 .pixi/envs 目录下。这意味着环境完全属于这个项目(Workspace)。如果查看 .pixi/envs 目录,你会看到每个环境都有一个目录, default 是通常默认使用的环境,如果你指定自定义环境,则会使用你指定的名称。

这些目录是 conda 环境,你可以像使用 conda 环境一样使用它们,但不能手动编辑,所有操作都必须通过 pixi.tomlpyproject.toml 文件进行。pixi 会始终确保环境与 pixi.lock 文件保持同步。如果环境不一致,所有使用该环境的命令都会自动更新,例如 pixi runpixi shell等命令。

在创建环境时,pixi 会添加一个包含一些元数据的小文件。该文件名为 pixi ,位于环境的 conda-meta 文件夹中。

如图所示:

该文件包含以下信息:

  • manifest_path :用于描述创建此环境的工作区的清单文件的路径
  • environment_name :环境的名称
  • pixi_version :用于创建此环境的 pixi 版本
  • environment_lock_file_hash :用于创建此环境的 pixi.lock文件的哈希值

environment_lock_file_hash 用于检查环境是否与 pixi.lock 文件同步。如果 pixi.lock 文件的哈希值与 pixi 文件中的哈希值不同,pixi 将更新环境。但是在通常情况下,哈希值比较无法检测到损坏的环境,但重新验证会重新安装该环境。默认情况下,所有修改锁定文件的命令以及 pixi install 命令都会触发重新验证。因此要触发完整的重新验证和安装,可以使用 pixi installpixi reinstall 命令。

4.2 清理环境

要清理环境,只需删除 .pixi/envs 目录,pixi 会在需要时重新创建环境。

1
rm -rf .pixi/envs

4.3 多环境

Multi Environment(多环境)的应用场景十分广泛,比如:

  • 一个workspace内有多个系统需求,例如 cuda 环境和 cpu 环境
  • 需要测试和pre-commit不需要安装在发布版本中,例如releasedev环境
  • 测试多个软件包版本 ,例如 py39py310polars 0.120.13版本

4.3.1 feature

feature定义了环境的一部分,但如果不作为环境的一部分则毫无用处。你可以在一个工作区中定义多个featurefeature可以包含 tasksdependenciesplatformschannels 等等 。你可以组合多个feature来创建一个环境。feature通过在清单文件中的表格中添加 [feature..*] 来定义。

在默认情况下,用户无需指定 [feature.<name>.dependencies](对于pyproject就是[tool.pixi.feature.<name>.dependencies],下同) ,可以直接填写 [dependencies] 。这些顶级表会被添加到default feature中,除非用户明确选择不添加,否则该feature会添加到每个环境中。

4.3.2 创建一个多环境的项目

创建一个新的项目,在default环境里安装numpy

1
2
3
pixi init multi_env --format pyproject
cd multi_env
pixi add numpy

在项目的 .pixi/envs/default 目录下,default环境就存储在这里。

4.3.3 添加feature

下面开始向工作区添加一个简单的 test feature。我们可以通过命令行或编辑 pyproject.toml 文件来完成此操作。这里我们将使用命令行,并将 pytest 依赖项添加到工作区的 test feature中。

1
pixi add --feature test pytest

此时查看pyproject.toml会发现自动添加了这几行:

1
2
[tool.pixi.feature.test.dependencies]
pytest = "*"

这与普通 dependencies 表完全相同,但仅当 test feature 是环境的一部分时才会被使用。

由于环境不仅仅包含 dependencies ,因此可以通过包含以下字段来描述 feature 字段:

  • dependencies :conda 包依赖项
  • pypi-dependencies :pypi 包依赖项
  • system-requirements :环境的系统需求
  • activation :环境的激活信息
  • platforms :该环境可以运行的平台
  • channels :用于创建环境的Channel。向Channel添加 priority 字段,以允许Channel连接而不是覆盖
  • tasks :特定功能的task,一个环境中的任务被选为该环境的默认task

4.3.4 添加另一个环境

接下来向工作区添加 test 环境,以便添加一些测试工具。我们可以通过命令行或编辑 pyproject.toml 文件来完成此操作。这里我们将使用命令行:

1
pixi workspace environment add test --feature test

此时查看pyproject.toml会发现自动添加了这几行:

1
2
3
[tool.pixi.environments]
# Define a 'test' environment that includes the 'test' feature
test = ["test"]

4.3.5 在新环境中运行任务

现在我们可以在新环境中运行任务了。

1
pixi run --environment test pytest --version

这条命令创建了测试环境,并在其中运行 pytest --version 命令。可以看到该环境将被添加到 .pixi/envs 目录中。

如果要查看环境,可以使用 pixi list 命令。

1
2
pixi list --environment default | grep pytest
pixi list --environment test | grep pytest

只有后者可以看到pytest软件包。

4.3.6 添加dev环境

在实践中,我们可能还需要一个dev feature

1
pixi add --feature dev jupyterlab ruff

添加dev环境,我们希望使用与default相同的依赖求解,因此使用--solve-group

1
2
pixi workspace environment add dev --feature dev  --solve-group default --force
pixi workspace environment add test --feature test --solve-group default --force

使用pixi list -x -e <env_name>查看,可以发现不同的环境具有完全相同的依赖项版本:

4.3.7 关于dependency-groups

实际上这二者都是同一个概念,只是在不同工具中的说法不同罢了,pixi使用的是后者。如果你的pyproject.toml中包含dependency-groups,比如:

1
2
[dependency-groups]
docs = ["sphinx"]

pixi 会将自动将其解释为同名的 feature, 并关联到 pypi-dependencies,因此,这就相当于:

1
2
[tool.pixi.feature.docs.pypi-dependencies]
sphinx = "*"

你可以通过以下命令验证:

1
pixi list -x -e dev

4.3.8 关于optional-dependencies

dependency-groups几乎相同,假设pyproject.toml中这么写:

1
2
3
4
5
6
[project.optional-dependencies]
dev = [
"ruff>=0.8.0",
"pre-commit>=3.5.0",
"pytest>=7.4.0",
]

pixi 会将自动将其解释为同名的 feature, 并关联到 pypi-dependencies,因此,这就相当于:

1
2
3
4
[tool.pixi.feature.dev.pypi-dependencies]
ruff = ">=0.8.0"
pre-commit = ">=3.5.0"
pytest = ">=7.4.0"

你可以通过以下命令验证:

1
pixi list -x -e dev

4.3.9 激活并使用对应环境

可以通过命令行或配置手动激活所需的环境。这种方法保证了环境无冲突,一次只允许激活一个功能集。

使用default环境:

1
2
pixi run python
# Runs python in the `default` environment

使用test环境:

1
2
3
pixi run -e test pytest
pixi run --environment test pytest
# Runs `pytest` in the `test` environment

在环境中运行任何命令:

1
2
pixi run -e test any_command
# Runs any_command in the `test` environment which doesn't require to be predefined as a task.

5. Config配置

pixi的配置文件一般名为config.toml,如果在多个位置均有该文件,则配置按以下优先级加载:

  1. 命令行参数如--change-ps1=false--tls-no-verify
  2. your_project/.pixi/config.toml:项目根目录下的配置
  3. $PIXI_HOME/config.tomlPIXI_HOME中的全局配置
  4. $HOME/.pixi/config.toml:用户HOME目录中的全局配置
  5. $HOME/.config/pixi/config.toml:用户指定配置
  6. /etc/pixi/config.toml:系统级配置

如果在优先级较高的位置找到配置文件,则从优先级较低的位置读取的配置值将被覆盖。

你可以通过运行 pixi info -vvv 来查看当前pixi在哪里寻找配置。

下面介绍一下我们平时主要用到的配置。

5.1 default-channels

1
default-channels = ["conda-forge"]

运行 pixi initpixi global install 时默认选择的Channel。默认仅选择 conda-forge

5.2 mirrors

使用mirrors可以配置Channel镜像。镜像的优先级根据列表顺序排列。pixi 会尝试从列表中的第一个镜像获取 conda 的repodata(最重要的文件)。repodata 包含所有软件包的 SHA256 哈希值,因此务必从可信来源获取此文件。

你可以替换某个镜像源,比如所有发送到 anaconda.org 上Channel的请求转发到 prefix.dev

1
2
3
[mirrors]
# redirect all requests for conda-forge to the prefix.dev mirror
"https://conda.anaconda.org/conda-forge" = ["https://prefix.dev/conda-forge"]

以下是南科大的conda镜像源,你可以将其写入配置文件中:

1
2
3
4
5
6
7
8
[mirrors]
"https://conda.anaconda.org/conda-forge" = ["https://mirrors.sustech.edu.cn/anaconda/cloud/conda-forge"]
"https://conda.anaconda.org/msys2" = ["https://mirrors.sustech.edu.cn/anaconda/cloud/msys2"]
"https://conda.anaconda.org/bioconda" = ["https://mirrors.sustech.edu.cn/anaconda/cloud/bioconda"]
"https://conda.anaconda.org/menpo" = ["https://mirrors.sustech.edu.cn/anaconda/cloud/menpo"]
"https://conda.anaconda.org/simpleitk" = ["https://mirrors.sustech.edu.cn/anaconda/cloud/simpleitk"]
"https://conda.anaconda.org/deepmodeling" = ["https://mirrors.sustech.edu.cn/anaconda/cloud/deepmodeling"]
"https://conda.anaconda.org/nvidia" = ["https://mirrors.sustech.edu.cn/anaconda-extra/cloud/nvidia"]

5.3 proxy-config

pixi 会优先考虑 https_proxy 等代理环境。也可以在 pixi 配置的 proxy-config 中设置代理,这将影响 pixi 的所有网络操作,例如解析、自动更新、下载等。目前 proxy-config 支持以下选项:

1
2
3
4
[proxy-config]
http = "http://proxy.example.com:8080/"
https = "http://proxy.example.com:8080/"
non-proxy-hosts = [".cn", "localhost", "[::1]"]

5.4 pypi-config

顾名思义这是PyPI的配置。

1
2
3
4
5
6
7
8
9
10
[pypi-config]
# 默认索引 URL
index-url = "https://pypi.org/simple"
# 额外的索引 URL 列表
extra-index-urls = ["https://pypi.org/simple2"]
# 使用 keyring python 包来存储和检索凭据,can be "subprocess" or "disabled"
keyring-provider = "subprocess"
# allow insecure connections to host
# 一个主机名列表(不包含协议或端口),访问 PyPI 镜像仓库时,将禁用这些主机名的 TLS 证书验证。这在处理使用自签名证书的内部 PyPI 镜像时非常有用。要全局禁用所有连接的 TLS 验证,应该改用 `tls-no-verify`
allow-insecure-host = ["localhost:8080"]

5.5 常用的config配置示例

可以配置到$HOME/.pixi/config.toml

1
2
3
4
5
6
7
8
9
10
11
12
13
default-channels = ["conda-forge", "bioconda"]

[mirrors]
"https://conda.anaconda.org/conda-forge" = ["https://mirrors.sustech.edu.cn/anaconda/cloud/conda-forge"]
"https://conda.anaconda.org/msys2" = ["https://mirrors.sustech.edu.cn/anaconda/cloud/msys2"]
"https://conda.anaconda.org/bioconda" = ["https://mirrors.sustech.edu.cn/anaconda/cloud/bioconda"]
"https://conda.anaconda.org/menpo" = ["https://mirrors.sustech.edu.cn/anaconda/cloud/menpo"]
"https://conda.anaconda.org/simpleitk" = ["https://mirrors.sustech.edu.cn/anaconda/cloud/simpleitk"]
"https://conda.anaconda.org/deepmodeling" = ["https://mirrors.sustech.edu.cn/anaconda/cloud/deepmodeling"]
"https://conda.anaconda.org/nvidia" = ["https://mirrors.sustech.edu.cn/anaconda-extra/cloud/nvidia"]

[pypi-config]
index-url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple"