conda的锁文件
项目描述
conda-lock
conda-lock是一个轻量级库,可用于为conda环境生成完全可重现的锁文件。
它通过为每个您希望生成锁文件的平台执行conda solve来实现这一点。
这还具有额外的优势,即充当conda的外部预解决方法,因为它生成的锁文件会导致conda求解器在从生成的锁文件安装软件包时不会调用。
为什么?
conda的environment.yml
文件对于定义所需的虚拟环境非常有用,但有时我们希望能够通过仅安装和下载所需的软件包来精确地复制一个环境。
这在gitops风格设置的情况下特别有用,在这种情况下,您使用conda在不同的地方设置虚拟环境。
安装
使用以下命令之一
pipx install conda-lock
condax install conda-lock
pip install conda-lock
conda install --channel=conda-forge --name=base conda-lock
mamba install --channel=conda-forge --name=base conda-lock
前两种选项是推荐的,因为它们将conda-lock安装到隔离环境中。(否则存在依赖冲突的风险。)
贡献
如果您想为conda-lock做出贡献,请参阅贡献指南,了解如何设置您的开发环境。
基本用法
# generate a multi-platform lockfile
conda-lock -f environment.yml -p osx-64 -p linux-64
# optionally, update the previous solution, using the latest version of
# pydantic that is compatible with the source specification
conda-lock --update pydantic
# create an environment from the lockfile
conda-lock install [-p {prefix}|-n {name}]
# alternatively, render a single-platform lockfile and use conda command directly
conda-lock render -p linux-64
conda create -n my-locked-env --file conda-linux-64.lock
与1.0版本兼容的用法(显式平台锁)
如果您在添加了统一锁文件的1.0版本发布之前已经使用conda-lock,您可以通过使用explicit
输出类型来获得该行为。
conda-lock --kind explicit -f environment.yml
高级用法
文件命名
默认情况下,conda-lock
将其输出存储在当前工作目录中的conda-lock.yml
中。该文件也将默认用于渲染、安装和更新操作。您可以使用例如以下方式提供不同的文件名。
conda-lock --lockfile superspecial.conda-lock.yml
默认情况下,渲染的explicit
和env
锁文件分别命名为"conda-{platform}.lock"
和"conda-{platform}.lock.yml"
。
如果您想覆盖该调用,请按如下方式调用conda-lock。
conda-lock -k explicit --filename-template "specific-{platform}.conda.lock"
复合规范
如果请求,conda-lock将根据几个文件构建一个规范列表。
conda-lock -f base.yml -f specific.yml -p linux-64 -k explicit --filename-template "specific-{platform}.lock"
在这种情况下,所有依赖项都会合并,所有channels
的有序并集将用作最终规范。
这适用于所有支持的文件类型。
通道覆盖
如果您需要覆盖environment.yml中指定的通道,可以覆盖conda-lock使用的通道。
conda-lock -c conda-forge -p linux-64
平台规范
您可以在environment.yml中使用(非标准)platforms
键直接指定您希望针对的平台。
# environment.yml
channels:
- conda-forge
dependencies:
- python=3.9
- pandas
platforms:
- linux-64
- osx-64
- win-64
- osx-arm64 # For Apple Silicon, e.g. M1/M2
- linux-aarch64 # aka arm64, use for Docker on Apple Silicon
- linux-ppc64le
如果使用-p
在命令行上指定目标平台,这些值将覆盖环境规范中的值。如果没有提供platforms
或-p
,conda-lock将回退到默认平台集。
默认类别
您可能希望将依赖项拆分到单独的文件中以进行更好的组织,例如,一个用于生产依赖项的environment.yml
和一个用于开发依赖项的dev-environment.yml
。您可以使用(非标准)category
键将单个文件解析的所有依赖项分配到类别。
# dev-environment.yml
channels:
- conda-forge
dependencies:
- pytest
- mypy=0.910
category: dev
默认类别是main
。
pip支持
conda-lock
还可以使用Poetry的依赖项求解器的打包副本锁定environment.yml中的dependencies.pip
部分。
私有pip仓库
目前,conda-lock
仅支持使用基本身份验证的旧版PyPi仓库。大多数自托管仓库,如Nexus、Artifactory等,都使用这种做法。您可以像配置通道一样配置私有pip仓库,例如。
channels:
- conda-forge
pip-repositories:
- http://$PIP_USER:$PIP_PASSWORD@private-pypi.org/api/pypi/simple
dependencies:
- python=3.11
- requests=2.26
- pip:
- fake-private-package==1.0.0
有关环境变量替换的规则,请参阅相关文档。
或者,您可以使用poetry
配置文件格式来配置私有PyPi仓库。配置文件应命名为config.toml
,并具有以下格式
[repositories.example]
url = "https://username:password@example.repo/simple"
可以通过以下命令确定该文件的位置:python -c 'from conda_lock._vendor.poetry.locations import CONFIG_DIR; print(CONFIG_DIR)'
除了使用pypi.org
之外,还会使用私有仓库。对于使用pyproject.toml
的项目,可以完全禁用pypi.org
。
--dev-dependencies/--no-dev-dependencies
默认情况下,conda-lock将在锁定规格中包含开发依赖项(如果锁定构建的文件支持它们)。这可以轻松禁用。
conda-lock --no-dev-dependencies -f ./recipe/meta.yaml
--check-input-hash
在某些情况下,您可能希望以某种自动化方式运行conda lock(例如,作为precommit),并且不希望如果该特定锁的底层输入规范未更改,则需要重新生成锁定文件。
conda-lock --check-input-hash -p linux-64
当输入文件的input_hash与给定锁定文件中存在的通道匹配时,该锁定文件将不会重新生成。
--strip-auth, --auth 和 --auth-file
默认情况下,conda-lock
将在锁定文件中留下私有conda通道的基本认证凭据。如果您希望从文件中删除认证,请提供--strip-auth
参数。
conda-lock --strip-auth -f environment.yml
要使用conda-lock install
带有基本认证凭据的锁定文件,您需要创建一个类似这样的.json
格式的认证文件:
{
"domain": "username:password"
}
如果您在同一域名内有多个需要不同认证的通道,您还可以指定通道,如下所示:
{
"domain.org/channel1": "username1:password1",
"domain.org/channel2": "username2:password2"
}
您可以通过--auth
作为字符串或通过--auth-file
作为文件路径来提供认证。
conda-lock install --auth-file auth.json conda-linux-64.lock
--virtual-package-spec
Conda使用运行时可用且用于系统功能依赖项的虚拟包。由于这些包通常不在您的本地执行平台上存在,conda-lock将使用对默认系统配置的合理猜测将它们注入到解决方案环境中。
如果您想覆盖要注入的虚拟包,可以创建一个类似这样的文件:
# virtual-packages.yml
subdirs:
linux-64:
packages:
__glibc: "2.17"
__cuda: "11.4"
win-64:
packages:
__cuda: "11.4"
conda-lock将自动使用当前工作目录中找到的virtual-packages.yml
。或者,也可以通过标志显式指定。
conda lock --virtual-package-spec virtual-packages-cuda.yml -p linux-64
输入哈希稳定性
虚拟包参与输入哈希,因此如果您使用不同的虚拟包集构建环境,则输入哈希将更改。此外,conda-lock的未来版本中默认虚拟包集可能还会增加。如果您希望输入哈希非常稳定,我们建议创建一个virtual-packages.yml
文件来锁定要考虑的虚拟包。
⚠️ 与micromamba一起使用
micromamba目前不支持删除所有发现的虚拟包的一些覆盖,因此解算时可用的虚拟包集可能比规范中指定的要大。
支持的文件来源
Conda lock支持不仅仅是environment.yml规范!
此外,conda-lock支持meta.yaml(conda-build)和pyproject.toml
(基于flit、pdm和poetry)。这些虽然有一些问题,但通常对于90%的使用情况来说足够好。
meta.yaml
conda-lock将尝试在meta.yaml中做出有根据的猜测来得出所需的环境规范。这并不保证对于具有许多选择器和输出的复杂配方有效。对于多输出配方,conda-lock将融合所有依赖项。如果这不符合您的需求,请回退到将规范指定为environment.yml
由于meta.yaml不包含通道信息,我们使用以下额外键来指定通道:
# meta.yaml
extra:
channels:
- conda-forge
- defaults
pyproject.toml
由于pyproject.toml
文件通常被Python包使用,因此直接从这些依赖项创建锁文件以单源化包的依赖项可能很有吸引力。这利用了一些conda-forge基础设施(pypi-mapping)来执行PyPI包名到相应conda包名的查找(例如docker
-> docker-py
)。在没有查找包的情况下,它假定PyPI名称和conda名称是相同的。
通道
# pyproject.toml
[tool.conda-lock]
channels = [
'conda-forge', 'defaults'
]
平台
类似于environment.yml,您可以指定要针对的默认平台
# pyproject.toml
[tool.conda-lock]
platforms = [
'osx-arm64', 'linux-64'
]
额外内容
如果您的pyproject.toml文件包含可选依赖项/额外内容,可以使用--extras
标志引用它们
# pyproject.toml
[tool.poetry.dependencies]
mandatory = "^1.0"
psycopg2 = { version = "^2.7", optional = true }
mysqlclient = { version = "^1.3", optional = true }
[tool.poetry.extras]
mysql = ["mysqlclient"]
pgsql = ["psycopg2"]
这些可以按以下方式引用
conda-lock --extra mysql --extra pgsql -f pyproject.toml
在生成使用额外内容的功能的锁文件时,建议使用此处所述的--filename-template
。
过滤额外内容
默认情况下,conda-lock将尝试解决在源中发现的所有额外内容/类别。这允许您渲染具有额外内容子集的显式锁,而无需进行新的解决。
然而,这假设您的额外内容可以一起安装。如果您想在解决阶段进行额外内容过滤,请使用标志--filter-extras
conda-lock --extra incompatiblea --filter-extras -f pyproject.toml
额外的conda依赖项
由于在pyproject.toml
中所有定义都是Python依赖项,如果需要指定一些非Python依赖项,可以通过在pyproject.toml
中添加以下部分来完成
# pyproject.toml
[tool.conda-lock.dependencies]
sqlite = ">=3.34"
pip依赖项
如果依赖项直接引用URL而不是包名和版本,conda-lock
将假定它是可pip安装的,例如
# pyproject.toml
[tool.poetry.dependencies]
python = "3.9"
pymage = {url = "https://github.com/MickaelRigault/pymage/archive/v1.0.tar.gz#sha256=11e99c4ea06b76ca7fb5b42d1d35d64139a4fa6f7f163a2f0f9cc3ea0b3c55eb"}
同样,如果依赖项明确标记为source = "pypi"
,它将被视为pip
依赖项,例如
[tool.poetry.dependencies]
python = "3.9"
ampel-ztf = {version = "^0.8.0-alpha.2", source = "pypi"}
如果依赖项在[tool.conda-lock.dependencies]
部分中明确标记为source = "pypi"
,它也将被视为pip
依赖项,例如
[tool.conda-lock.dependencies]
ampel-ztf = {source = "pypi"}
将非conda依赖项源默认设置为PyPI
或者,上述行为默认适用于定义在[tool.conda-lock.dependencies]
之外的依赖项,即
- 默认为
pip
依赖项的[tool.poetry.dependencies]
、[project.dependencies]
等 - 默认为
conda
依赖项的[tool.conda-lock.dependencies]
通过在[tool.conda-lock]
部分中显式提供default-non-conda-source = "pip"
,例如
[tool.conda-lock]
default-non-conda-source = "pip"
在所有情况下,可pip安装的包的依赖项也将使用pip安装,除非它们已被conda依赖项请求。
仅锁定conda-lock依赖项
要仅锁定在[tool.conda-lock]
下指定的依赖项(即跳过其他地方指定的所有依赖项),请在[tool.conda-lock]
部分中显式提供skip-non-conda-lock = true
,例如
[tool.conda-lock]
skip-non-conda-lock = true
禁用pypi.org
当使用私有pip仓库时,可以完全禁用pypi.org
。当使用conda-lock
位于不允许访问pypi.org
的网络代理后面时,这可能很有用。
[tool.conda-lock]
allow-pypi-requests = false
Dockerfile示例
为了在docker-style环境中使用conda-lock,您想要将锁文件添加到docker容器中。为了刷新锁文件,只需再次运行conda-lock
。
给定一个类似如下的文件树
Dockerfile
environment.yaml
* conda-linux-64.lock
您想要的dockerfile结构类似于以下
# Dockerfile
# Build container
FROM continuumio/miniconda:latest as conda
ADD conda-linux-64.lock /locks/conda-linux-64.lock
RUN conda create -p /opt/env --copy --file /locks/conda-linux-64.lock
# Primary container
FROM gcr.io/distroless/base-debian10
COPY --from=conda /opt/env /opt/env
项目详情
下载文件
下载适合您平台的文件。如果您不确定选择哪个,请了解有关安装包的更多信息。