跳转到主要内容

统一Conda和Pip需求管理。

项目描述

🚀 UniDep - 统一Conda和Pip依赖管理 🚀

UniDep logo

PyPI Build Status CodeCov GitHub Repo stars Documentation Python Bytes

UniDep通过统一Conda和Pip包在一个系统中,简化了Python项目依赖管理。在我们的FAQ中学习何时使用UniDep。

在Python项目中处理依赖项可能具有挑战性,尤其是在处理Python和非Python包时。这通常会导致混乱和低效率,因为开发者需要在多个依赖文件之间切换。

  • 📝 统一依赖文件:使用requirements.yamlpyproject.toml在一个地方管理Conda和Pip依赖。
  • ⚙️ 构建系统集成:与Setuptools和Hatchling集成,在执行pip install ./your-package时自动处理依赖。
  • 💻 一键安装unidep install轻松处理Conda、Pip和本地依赖。
  • 🏢 单一仓库友好:将(多个)requirements.yamlpyproject.toml文件转换为单个Conda environment.yaml文件,并维护完全一致的全球每个子包conda-lock文件。
  • 🌍 平台特定支持:指定不同操作系统或架构的依赖项。
  • 🔧 pip-compile 集成:使用 pip-compilerequirements.yamlpyproject.toml 文件生成完全固定的 requirements.txt 文件。
  • 🔒 与 conda-lock 集成:利用 conda-lock 从多个 requirements.yamlpyproject.toml 文件生成完全固定的 conda-lock.yml 文件。
  • 🤓 硬核统计:用 Python 编写,测试覆盖率 >99%,完全类型化,所有 Ruff 规则已启用,易于扩展,依赖最少。

unidep 旨在使 Python 项目的依赖管理尽可能简单高效。现在就试试,简化你的开发过程!

[!TIP] 查看下面的示例 requirements.yamlpyproject.toml

:books: 目录

:package: 安装

要安装 unidep,请运行以下命令之一,使用 pipx(推荐)、pipconda

pipx install "unidep[all]"  # Recommended (install as a standalone CLI)

pip install "unidep[all]"

conda install -c conda-forge unidep

:memo: requirements.yamlpyproject.toml 结构

unidep 允许使用一个

  1. requirements.yaml 文件,具有特定格式(与 Conda 的 environment.yaml 文件类似但 不同)或
  2. pyproject.toml 文件,包含 [tool.unidep] 部分。

两个文件都包含以下键

  • name(可选):用于文档,输出中不使用。
  • channels:包的 conda 通道列表,如 conda-forge
  • dependencies:Conda 和 Pip 包的混合。
  • local_dependencies(可选):包含其他 requirements.yamlpyproject.toml 文件的路径列表,以包含在内。
  • optional_dependencies(可选):包含可选依赖项的字典。
  • platforms(可选):支持的平台列表(在 conda-lock 中使用)。

无论您使用 requirements.yaml 还是 pyproject.toml 文件,都可以在任一文件中指定相同的信息。选择最适合您的项目的格式。

示例

示例 requirements.yaml

requirements.yaml 文件的示例

name: example_environment
channels:
  - conda-forge
dependencies:
  - numpy                   # same name on conda and pip
  - conda: python-graphviz  # When names differ between Conda and Pip
    pip: graphviz
  - pip: slurm-usage >=1.1.0,<2  # pip-only
  - conda: mumps                 # conda-only
  # Use platform selectors
  - conda: cuda-toolkit =11.8    # [linux64]
local_dependencies:
  - ../other-project-using-unidep     # include other projects that use unidep
  - ../common-requirements.yaml       # include other requirements.yaml files
  - ../project-not-managed-by-unidep  # 🚨 Skips its dependencies!
optional_dependencies:
  test:
    - pytest
  full:
    - ../other-local-dep[test]  # include its optional 'test' dependencies
platforms:  # (Optional) specify platforms that are supported (used in conda-lock)
  - linux-64
  - osx-arm64

[!IMPORTANT] unidep 可以在 pip install 过程中处理此内容,创建可安装的 environment.yamlconda-lock.yml 文件,等等!

[!NOTE] 对于包含多个可安装项目的更深入示例,请参阅 example 目录。

示例 pyproject.toml

或者,可以在 pyproject.toml 文件的 [tool.unidep] 部分完全配置依赖项

[tool.unidep]
channels = ["conda-forge"]
dependencies = [
    "numpy",                                         # same name on conda and pip
    { conda = "python-graphviz", pip = "graphviz" }, # When names differ between Conda and Pip
    { pip = "slurm-usage >=1.1.0,<2" },              # pip-only
    { conda = "mumps" },                             # conda-only
    { conda = "cuda-toolkit =11.8:linux64" }         # Use platform selectors by appending `:linux64`
]
local_dependencies = [
    "../other-project-using-unidep",    # include other projects that use unidep
    "../common-requirements.yaml",      # include other requirements.yaml files
    "../project-not-managed-by-unidep"  # 🚨 Skips its dependencies!
]
optional_dependencies = {
    test = ["pytest"],
    full = ["../other-local-dep[test]"]  # include its optional 'test' dependencies
}
platforms = [ # (Optional) specify platforms that are supported (used in conda-lock)
    "linux-64",
    "osx-arm64"
]

这种数据结构与 requirements.yaml 格式相同,除了 name 字段和 平台选择器。在 requirements.yaml 文件中,可以使用例如 # [linux64],在 pyproject.toml 文件中则是包名称末尾的 :linux64

请参阅构建系统集成以获取有关如何使用不同的构建系统(Setuptools或Hatchling)设置unidep的更多信息。

[!重要] 在这些文档中,我们通常为了简便起见提到requirements.yaml格式,但相同的信息也可以在pyproject.toml中指定。在requirements.yaml中能做的一切,在pyproject.toml中也能做!

重点

  • 标准名称(例如,- numpy)假设在Conda和Pip中是相同的。
  • 使用具有conda: <package>pip: <package>的字典来指定跨平台的不同名称。
  • 使用pip:来指定仅通过Pip可用的包。
  • 使用conda:来指定仅通过Conda可用的包。
  • 使用# [selector](仅YAML)或package:selector来指定特定平台的依赖项。
  • 使用local_dependencies:来包含其他requirements.yamlpyproject.toml文件并将它们合并成一个。这也允许包含不受unidep管理的项目,但请注意,这将跳过它们的依赖项!
  • 使用optional_dependencies:来指定可选依赖项。可以像unidep install ".[test]"pip install ".[test]"一样安装。
  • 使用platforms:来指定支持的平台。如果省略,则假设所有平台都受支持。

这里我们使用YAML表示法,但相同的信息也可以在pyproject.toml中指定。

支持的版本固定

UniDep支持一系列版本锁定运算符(与Conda相同)

  • 标准版本约束:使用标准运算符(如=><>=<=)指定精确版本或范围。

    • 示例:=1.0.0>1.0.0, <2.0.0
  • 版本排除:使用!=排除特定版本。

    • 示例:!=1.5.0
  • 冗余锁定解析:自动解析冗余版本指定。

    • 示例:>1.0.0, >0.5.0简化为>1.0.0
  • 版本冲突检测:对于相互矛盾的锁定,引发错误以保持依赖项的完整性。有关更多信息,请参阅冲突解决部分。

    • 示例:指定>2.0.0, <1.5.0触发VersionConflictError
  • 无效锁定检测:检测并引发错误,以识别未识别或格式不正确的版本指定。

  • Conda构建锁定:UniDep还支持Conda的构建锁定,允许您在锁定模式中指定构建。

    • 示例:Conda支持像qsimcirq * cuda*vtk * *egl*这样的构建锁定。
    • 限制:虽然UniDep允许这样的构建锁定,但它要求每个包有一个单独的锁定。UniDep无法解决为同一包指定多个构建锁定的冲突。
      • 示例:UniDep可以处理qsimcirq * cuda*,但它无法解决同时指定qsimcirq * cuda*qsimcirq * cpu*的情况。
  • 其他特殊情况:除了Conda构建锁定外,UniDep还支持所有特殊锁定格式,例如VCS(版本控制系统)URL或本地文件路径。这包括像package @ git+https://git/repo/herepackage @ file:///path/to/package这样的格式。但是,UniDep有一个限制:它可以处理每个包的一个特殊锁定。这些特殊锁定可以与未锁定的版本指定结合使用,但不能与同一包的多个特殊锁定格式结合使用。

    • 示例:UniDep可以管理在同一个requirements.yaml中指定的依赖项,例如package @ git+https://git/repo/herepackage。但是,它无法解决同时为同一包指定package @ git+https://git/repo/herepackage @ file:///path/to/package的情况。

[!警告] 固定验证和组合:UniDep仅在指定同一包的多个不同固定时,才主动验证和/或组合固定。这意味着如果您的requirements.yaml文件包含单个包的多个固定,UniDep将尝试将它们解析为一个单一、一致的规范。然而,如果固定存在矛盾或不兼容,UniDep将引发错误以通知您冲突。

冲突解决

unidep具有冲突解决机制,用于管理requirements.yamlpyproject.toml文件中的版本冲突和平台特定依赖项。

工作原理

  • 版本固定优先级unidep在同一个包被多次指定时,优先考虑版本固定的包。例如,如果既列出了foo又列出了foo <1,则由于其特定的版本固定,将选择foo <1

  • 平台特定版本固定unidep通过优先选择具有最窄平台范围的版本来解决平台特定依赖项冲突。例如,给定foo <3 # [linux64]foo >1,它仅在Linux-64上安装foo >1,<3,在其他平台上安装foo >1

  • 难以解决的冲突:当冲突无法解决(例如,foo >1foo <1)时,unidep将引发异常。

平台选择器

此工具支持一系列平台选择器,允许根据用户的操作系统和体系结构对依赖项进行特定处理。此功能特别适用于管理不同环境中的条件依赖项。

支持的选择器

支持以下选择器

  • linux:适用于所有基于Linux的系统。
  • linux64:特别适用于64位Linux系统。
  • aarch64:适用于ARM64架构的Linux系统。
  • ppc64le:适用于PowerPC 64位Little Endian架构的Linux。
  • osx:适用于所有macOS系统。
  • osx64:特别适用于64位macOS系统。
  • arm64:适用于ARM64架构的macOS系统(Apple Silicon)。
  • macososx的替代方案,用于macOS系统。
  • unix:适用于所有类似UNIX的系统(包括Linux和macOS)。
  • win:适用于所有Windows系统。
  • win64:特别适用于64位Windows系统。

用法

选择器用于requirements.yaml文件,以根据平台条件包含依赖项

dependencies:
  - some-package >=1  # [unix]
  - another-package   # [win]
  - special-package   # [osx64]
  - pip: cirq         # [macos win]
    conda: cirq       # [linux]

或当使用pyproject.toml代替requirements.yaml

[tool.unidep]
dependencies = [
    "some-package >=1:unix",
    "another-package:win",
    "special-package:osx64",
    { pip = "cirq:macos win", conda = "cirq:linux" },
]

在以下示例中

  • some-package仅在UNIX-like环境中(Linux和macOS)包括。
  • another-package特定于Windows。
  • special-package仅在64位macOS系统中包括。
  • cirq在macOS和Windows上由pip管理,在Linux上由conda管理。这展示了您如何根据平台指定不同的包管理器。

请注意,package-name:unix语法也可以在requirements.yaml文件中使用,但package-name # [unix]语法在pyproject.toml中不受支持。

实现

unidep解析这些选择器,并根据安装的平台过滤依赖项。它还用于创建不同平台之间可移植的环境和锁文件,确保每个环境都安装了适当的依赖项。

:jigsaw: 建筑系统集成

[!提示] 请参阅example/以获取使用unidep与不同构建系统一起工作的示例。

unidep无缝集成到流行的Python构建系统中,以简化项目的依赖项管理。

示例包

探索以下可安装的示例包,了解unidep如何与不同的构建工具和配置集成

项目 构建工具 pyproject.toml requirements.yaml setup.py
setup_py_project setuptools
setuptools_project setuptools
pyproject_toml_project setuptools
hatch_project hatch
hatch2_project hatch

Setuptools 集成

对于使用 setuptools 的项目,请在 pyproject.toml 中配置 unidep,并指定依赖项在 requirements.yaml 文件中,或者将它们也包含在 pyproject.toml 中。

  • 仅使用 pyproject.tomlpyproject.toml 中的 [project.dependencies] 字段会自动从 requirements.yamlpyproject.toml 中的 [tool.unidep] 部分填充。
  • 使用 setup.pysetup.py 中的 install_requires 字段会自动反映在 requirements.yamlpyproject.toml 中指定的依赖项。

示例 pyproject.toml 配置:

[build-system]
build-backend = "setuptools.build_meta"
requires = ["setuptools", "unidep"]

[project]
dynamic = ["dependencies"]

Hatchling 集成

对于使用 Hatch 管理的项目,可以在 pyproject.toml 中配置 unidep 以自动处理来自 requirements.yamlpyproject.toml 中的 [tool.unidep] 部分的依赖项。

Hatch 配置示例:

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

[project]
dynamic = ["dependencies"]
# Additional project configurations

[tool.hatch]
# Additional Hatch configurations

[tool.hatch.metadata.hooks.unidep]

:desktop_computer: 作为 CLI

更多信息请参阅 示例 或查看 unidep -h 的输出以获取可用的子命令

usage: unidep [-h]
              {merge,install,install-all,conda-lock,pip-compile,pip,conda,version}
              ...

Unified Conda and Pip requirements management.

positional arguments:
  {merge,install,install-all,conda-lock,pip-compile,pip,conda,version}
                        Subcommands
    merge               Combine multiple (or a single) `requirements.yaml` or
                        `pyproject.toml` files into a single Conda installable
                        `environment.yaml` file.
    install             Automatically install all dependencies from one or
                        more `requirements.yaml` or `pyproject.toml` files.
                        This command first installs dependencies with Conda,
                        then with Pip. Finally, it installs local packages
                        (those containing the `requirements.yaml` or
                        `pyproject.toml` files) using `pip install [-e]
                        ./project`.
    install-all         Install dependencies from all `requirements.yaml` or
                        `pyproject.toml` files found in the current directory
                        or specified directory. This command first installs
                        dependencies using Conda, then Pip, and finally the
                        local packages.
    conda-lock          Generate a global `conda-lock.yml` file for a
                        collection of `requirements.yaml` or `pyproject.toml`
                        files. Additionally, create individual `conda-
                        lock.yml` files for each `requirements.yaml` or
                        `pyproject.toml` file consistent with the global lock
                        file.
    pip-compile         Generate a fully pinned `requirements.txt` file from
                        one or more `requirements.yaml` or `pyproject.toml`
                        files using `pip-compile` from `pip-tools`. This
                        command consolidates all pip dependencies defined in
                        the `requirements.yaml` or `pyproject.toml` files and
                        compiles them into a single `requirements.txt` file,
                        taking into account the specific versions and
                        dependencies of each package.
    pip                 Get the pip requirements for the current platform
                        only.
    conda               Get the conda requirements for the current platform
                        only.
    version             Print version information of unidep.

options:
  -h, --help            show this help message and exit

unidep merge

使用 unidep merge 扫描目录以查找 requirements.yaml 文件并合并到 environment.yaml 文件中。有关更多信息,请参阅 unidep merge -h

usage: unidep merge [-h] [-o OUTPUT] [-n NAME] [--stdout]
                    [--selector {sel,comment}] [-d DIRECTORY] [--depth DEPTH]
                    [-v]
                    [--platform {linux-64,linux-aarch64,linux-ppc64le,osx-64,osx-arm64,win-64}]
                    [--skip-dependency SKIP_DEPENDENCY]
                    [--ignore-pin IGNORE_PIN] [--overwrite-pin OVERWRITE_PIN]

Combine multiple (or a single) `requirements.yaml` or `pyproject.toml` files
into a single Conda installable `environment.yaml` file. Example usage:
`unidep merge --directory . --depth 1 --output environment.yaml` to search for
`requirements.yaml` or `pyproject.toml` files in the current directory and its
subdirectories and create `environment.yaml`. These are the defaults, so you
can also just run `unidep merge`.

options:
  -h, --help            show this help message and exit
  -o OUTPUT, --output OUTPUT
                        Output file for the conda environment, by default
                        `environment.yaml`
  -n NAME, --name NAME  Name of the conda environment, by default `myenv`
  --stdout              Output to stdout instead of a file
  --selector {sel,comment}
                        The selector to use for the environment markers, if
                        `sel` then `- numpy # [linux]` becomes `sel(linux):
                        numpy`, if `comment` then it remains `- numpy #
                        [linux]`, by default `sel`
  -d DIRECTORY, --directory DIRECTORY
                        Base directory to scan for `requirements.yaml` or
                        `pyproject.toml` file(s), by default `.`
  --depth DEPTH         Maximum depth to scan for `requirements.yaml` or
                        `pyproject.toml` files, by default 1
  -v, --verbose         Print verbose output
  --platform {linux-64,linux-aarch64,linux-ppc64le,osx-64,osx-arm64,win-64}, -p {linux-64,linux-aarch64,linux-ppc64le,osx-64,osx-arm64,win-64}
                        The platform(s) to get the requirements for. Multiple
                        platforms can be specified. By default, the current
                        platform (`linux-64`) is used.
  --skip-dependency SKIP_DEPENDENCY
                        Skip installing a specific dependency that is in one
                        of the `requirements.yaml` or `pyproject.toml` files.
                        This option can be used multiple times, each time
                        specifying a different package to skip. For example,
                        use `--skip-dependency pandas` to skip installing
                        pandas.
  --ignore-pin IGNORE_PIN
                        Ignore the version pin for a specific package, e.g.,
                        `--ignore-pin numpy`. This option can be repeated to
                        ignore multiple packages.
  --overwrite-pin OVERWRITE_PIN
                        Overwrite the version pin for a specific package,
                        e.g., `--overwrite-pin 'numpy=1.19.2'`. This option
                        can be repeated to overwrite the pins of multiple
                        packages.

unidep install

requirements.yaml 文件上使用 unidep install,使用 conda 在当前平台上安装依赖项,然后使用 pip 安装剩余的依赖项,最后使用 pip install [-e] . 安装当前包。有关更多信息,请参阅 unidep install -h

usage: unidep install [-h] [-v] [-e] [--skip-local] [--skip-pip]
                      [--skip-conda] [--skip-dependency SKIP_DEPENDENCY]
                      [--no-dependencies]
                      [--conda-executable {conda,mamba,micromamba}]
                      [--conda-env-name CONDA_ENV_NAME | --conda-env-prefix CONDA_ENV_PREFIX]
                      [--dry-run] [--ignore-pin IGNORE_PIN]
                      [--overwrite-pin OVERWRITE_PIN] [-f CONDA_LOCK_FILE]
                      files [files ...]

Automatically install all dependencies from one or more `requirements.yaml` or
`pyproject.toml` files. This command first installs dependencies with Conda,
then with Pip. Finally, it installs local packages (those containing the
`requirements.yaml` or `pyproject.toml` files) using `pip install [-e]
./project`. Example usage: `unidep install .` for a single project. For
multiple projects: `unidep install ./project1 ./project2`. The command accepts
both file paths and directories containing a `requirements.yaml` or
`pyproject.toml` file. Use `--editable` or `-e` to install the local packages
in editable mode. See `unidep install-all` to install all `requirements.yaml`
or `pyproject.toml` files in and below the current folder.

positional arguments:
  files                 The `requirements.yaml` or `pyproject.toml` file(s) to
                        parse or folder(s) that contain those file(s), by
                        default `.`

options:
  -h, --help            show this help message and exit
  -v, --verbose         Print verbose output
  -e, --editable        Install the project in editable mode
  --skip-local          Skip installing local dependencies
  --skip-pip            Skip installing pip dependencies from
                        `requirements.yaml` or `pyproject.toml`
  --skip-conda          Skip installing conda dependencies from
                        `requirements.yaml` or `pyproject.toml`
  --skip-dependency SKIP_DEPENDENCY
                        Skip installing a specific dependency that is in one
                        of the `requirements.yaml` or `pyproject.toml` files.
                        This option can be used multiple times, each time
                        specifying a different package to skip. For example,
                        use `--skip-dependency pandas` to skip installing
                        pandas.
  --no-dependencies     Skip installing dependencies from `requirements.yaml`
                        or `pyproject.toml` file(s) and only install local
                        package(s). Useful after installing a `conda-lock.yml`
                        file because then all dependencies have already been
                        installed.
  --conda-executable {conda,mamba,micromamba}
                        The conda executable to use
  --conda-env-name CONDA_ENV_NAME
                        Name of the conda environment, if not provided, the
                        currently active environment name is used, unless
                        `--conda-env-prefix` is provided
  --conda-env-prefix CONDA_ENV_PREFIX
                        Path to the conda environment, if not provided, the
                        currently active environment path is used, unless
                        `--conda-env-name` is provided
  --dry-run, --dry      Only print the commands that would be run
  --ignore-pin IGNORE_PIN
                        Ignore the version pin for a specific package, e.g.,
                        `--ignore-pin numpy`. This option can be repeated to
                        ignore multiple packages.
  --overwrite-pin OVERWRITE_PIN
                        Overwrite the version pin for a specific package,
                        e.g., `--overwrite-pin 'numpy=1.19.2'`. This option
                        can be repeated to overwrite the pins of multiple
                        packages.
  -f CONDA_LOCK_FILE, --conda-lock-file CONDA_LOCK_FILE
                        Path to the `conda-lock.yml` file to use for creating
                        the new environment. Assumes that the lock file
                        contains all dependencies. Must be used with `--conda-
                        env-name` or `--conda-env-prefix`.

unidep install-all

在包含 requirements.yaml 文件的文件夹上使用 unidep install-all,使用 conda 在当前平台上安装依赖项,然后使用 pip 安装剩余的依赖项,最后使用 pip install [-e] ./package1 ./package2 安装当前包。有关更多信息,请参阅 unidep install-all -h

usage: unidep install [-h] [-v] [-e] [--skip-local] [--skip-pip]
                      [--skip-conda] [--skip-dependency SKIP_DEPENDENCY]
                      [--no-dependencies]
                      [--conda-executable {conda,mamba,micromamba}]
                      [--conda-env-name CONDA_ENV_NAME | --conda-env-prefix CONDA_ENV_PREFIX]
                      [--dry-run] [--ignore-pin IGNORE_PIN]
                      [--overwrite-pin OVERWRITE_PIN] [-f CONDA_LOCK_FILE]
                      files [files ...]

Automatically install all dependencies from one or more `requirements.yaml` or
`pyproject.toml` files. This command first installs dependencies with Conda,
then with Pip. Finally, it installs local packages (those containing the
`requirements.yaml` or `pyproject.toml` files) using `pip install [-e]
./project`. Example usage: `unidep install .` for a single project. For
multiple projects: `unidep install ./project1 ./project2`. The command accepts
both file paths and directories containing a `requirements.yaml` or
`pyproject.toml` file. Use `--editable` or `-e` to install the local packages
in editable mode. See `unidep install-all` to install all `requirements.yaml`
or `pyproject.toml` files in and below the current folder.

positional arguments:
  files                 The `requirements.yaml` or `pyproject.toml` file(s) to
                        parse or folder(s) that contain those file(s), by
                        default `.`

options:
  -h, --help            show this help message and exit
  -v, --verbose         Print verbose output
  -e, --editable        Install the project in editable mode
  --skip-local          Skip installing local dependencies
  --skip-pip            Skip installing pip dependencies from
                        `requirements.yaml` or `pyproject.toml`
  --skip-conda          Skip installing conda dependencies from
                        `requirements.yaml` or `pyproject.toml`
  --skip-dependency SKIP_DEPENDENCY
                        Skip installing a specific dependency that is in one
                        of the `requirements.yaml` or `pyproject.toml` files.
                        This option can be used multiple times, each time
                        specifying a different package to skip. For example,
                        use `--skip-dependency pandas` to skip installing
                        pandas.
  --no-dependencies     Skip installing dependencies from `requirements.yaml`
                        or `pyproject.toml` file(s) and only install local
                        package(s). Useful after installing a `conda-lock.yml`
                        file because then all dependencies have already been
                        installed.
  --conda-executable {conda,mamba,micromamba}
                        The conda executable to use
  --conda-env-name CONDA_ENV_NAME
                        Name of the conda environment, if not provided, the
                        currently active environment name is used, unless
                        `--conda-env-prefix` is provided
  --conda-env-prefix CONDA_ENV_PREFIX
                        Path to the conda environment, if not provided, the
                        currently active environment path is used, unless
                        `--conda-env-name` is provided
  --dry-run, --dry      Only print the commands that would be run
  --ignore-pin IGNORE_PIN
                        Ignore the version pin for a specific package, e.g.,
                        `--ignore-pin numpy`. This option can be repeated to
                        ignore multiple packages.
  --overwrite-pin OVERWRITE_PIN
                        Overwrite the version pin for a specific package,
                        e.g., `--overwrite-pin 'numpy=1.19.2'`. This option
                        can be repeated to overwrite the pins of multiple
                        packages.
  -f CONDA_LOCK_FILE, --conda-lock-file CONDA_LOCK_FILE
                        Path to the `conda-lock.yml` file to use for creating
                        the new environment. Assumes that the lock file
                        contains all dependencies. Must be used with `--conda-
                        env-name` or `--conda-env-prefix`.

unidep conda-lock

requirements.yaml 文件上使用 unidep conda-lock 并输出 conda-lock 文件。如果使用包含多个子包(具有自己的 requirements.yaml 文件)的单一代码库,则可以为每个子包生成锁文件。有关更多信息,请参阅 unidep conda-lock -h

usage: unidep conda-lock [-h] [--only-global] [--lockfile LOCKFILE]
                         [--check-input-hash] [-d DIRECTORY] [--depth DEPTH]
                         [-f FILE] [-v]
                         [--platform {linux-64,linux-aarch64,linux-ppc64le,osx-64,osx-arm64,win-64}]
                         [--skip-dependency SKIP_DEPENDENCY]
                         [--ignore-pin IGNORE_PIN]
                         [--overwrite-pin OVERWRITE_PIN]
                         ...

Generate a global `conda-lock.yml` file for a collection of
`requirements.yaml` or `pyproject.toml` files. Additionally, create individual
`conda-lock.yml` files for each `requirements.yaml` or `pyproject.toml` file
consistent with the global lock file. Example usage: `unidep conda-lock
--directory ./projects` to generate conda-lock files for all
`requirements.yaml` or `pyproject.toml` files in the `./projects` directory.
Use `--only-global` to generate only the global lock file. The `--check-input-
hash` option can be used to avoid regenerating lock files if the input hasn't
changed.

positional arguments:
  extra_flags           Extra flags to pass to `conda-lock lock`. These flags
                        are passed directly and should be provided in the
                        format expected by `conda-lock lock`. For example,
                        `unidep conda-lock -- --micromamba`. Note that the
                        `--` is required to separate the flags for `unidep
                        conda-lock` from the flags for `conda-lock lock`.

options:
  -h, --help            show this help message and exit
  --only-global         Only generate the global lock file
  --lockfile LOCKFILE   Specify a path for the global lockfile (default:
                        `conda-lock.yml` in current directory). Path should be
                        relative, e.g., `--lockfile ./locks/example.conda-
                        lock.yml`.
  --check-input-hash    Check existing input hashes in lockfiles before
                        regenerating lock files. This flag is directly passed
                        to `conda-lock`.
  -d DIRECTORY, --directory DIRECTORY
                        Base directory to scan for `requirements.yaml` or
                        `pyproject.toml` file(s), by default `.`
  --depth DEPTH         Maximum depth to scan for `requirements.yaml` or
                        `pyproject.toml` files, by default 1
  -f FILE, --file FILE  A single `requirements.yaml` or `pyproject.toml` file
                        to use, or folder that contains that file. This is an
                        alternative to using `--directory` which searches for
                        all `requirements.yaml` or `pyproject.toml` files in
                        the directory and its subdirectories.
  -v, --verbose         Print verbose output
  --platform {linux-64,linux-aarch64,linux-ppc64le,osx-64,osx-arm64,win-64}, -p {linux-64,linux-aarch64,linux-ppc64le,osx-64,osx-arm64,win-64}
                        The platform(s) to get the requirements for. Multiple
                        platforms can be specified. By default, the current
                        platform (`linux-64`) is used.
  --skip-dependency SKIP_DEPENDENCY
                        Skip installing a specific dependency that is in one
                        of the `requirements.yaml` or `pyproject.toml` files.
                        This option can be used multiple times, each time
                        specifying a different package to skip. For example,
                        use `--skip-dependency pandas` to skip installing
                        pandas.
  --ignore-pin IGNORE_PIN
                        Ignore the version pin for a specific package, e.g.,
                        `--ignore-pin numpy`. This option can be repeated to
                        ignore multiple packages.
  --overwrite-pin OVERWRITE_PIN
                        Overwrite the version pin for a specific package,
                        e.g., `--overwrite-pin 'numpy=1.19.2'`. This option
                        can be repeated to overwrite the pins of multiple
                        packages.

unidep pip-compile

requirements.yaml 文件上使用 unidep pip-compile 并使用来自 pip-toolspip-compile 输出完全锁定的 requirements.txt 文件。有关更多信息,请参阅 unidep pip-compile -h

usage: unidep pip-compile [-h] [-o OUTPUT_FILE] [-d DIRECTORY] [--depth DEPTH]
                          [-v]
                          [--platform {linux-64,linux-aarch64,linux-ppc64le,osx-64,osx-arm64,win-64}]
                          [--skip-dependency SKIP_DEPENDENCY]
                          [--ignore-pin IGNORE_PIN]
                          [--overwrite-pin OVERWRITE_PIN]
                          ...

Generate a fully pinned `requirements.txt` file from one or more
`requirements.yaml` or `pyproject.toml` files using `pip-compile` from `pip-
tools`. This command consolidates all pip dependencies defined in the
`requirements.yaml` or `pyproject.toml` files and compiles them into a single
`requirements.txt` file, taking into account the specific versions and
dependencies of each package. Example usage: `unidep pip-compile --directory
./projects` to generate a `requirements.txt` file for all `requirements.yaml`
or `pyproject.toml` files in the `./projects` directory. Use `--output-file
requirements.txt` to specify a different output file.

positional arguments:
  extra_flags           Extra flags to pass to `pip-compile`. These flags are
                        passed directly and should be provided in the format
                        expected by `pip-compile`. For example, `unidep pip-
                        compile -- --generate-hashes --allow-unsafe`. Note
                        that the `--` is required to separate the flags for
                        `unidep pip-compile` from the flags for `pip-compile`.

options:
  -h, --help            show this help message and exit
  -o OUTPUT_FILE, --output-file OUTPUT_FILE
                        Output file for the pip requirements, by default
                        `requirements.txt`
  -d DIRECTORY, --directory DIRECTORY
                        Base directory to scan for `requirements.yaml` or
                        `pyproject.toml` file(s), by default `.`
  --depth DEPTH         Maximum depth to scan for `requirements.yaml` or
                        `pyproject.toml` files, by default 1
  -v, --verbose         Print verbose output
  --platform {linux-64,linux-aarch64,linux-ppc64le,osx-64,osx-arm64,win-64}, -p {linux-64,linux-aarch64,linux-ppc64le,osx-64,osx-arm64,win-64}
                        The platform(s) to get the requirements for. Multiple
                        platforms can be specified. By default, the current
                        platform (`linux-64`) is used.
  --skip-dependency SKIP_DEPENDENCY
                        Skip installing a specific dependency that is in one
                        of the `requirements.yaml` or `pyproject.toml` files.
                        This option can be used multiple times, each time
                        specifying a different package to skip. For example,
                        use `--skip-dependency pandas` to skip installing
                        pandas.
  --ignore-pin IGNORE_PIN
                        Ignore the version pin for a specific package, e.g.,
                        `--ignore-pin numpy`. This option can be repeated to
                        ignore multiple packages.
  --overwrite-pin OVERWRITE_PIN
                        Overwrite the version pin for a specific package,
                        e.g., `--overwrite-pin 'numpy=1.19.2'`. This option
                        can be repeated to overwrite the pins of multiple
                        packages.

unidep pip

requirements.yaml 文件上使用 unidep pip 并输出当前平台上的 pip 可安装依赖项(默认)。有关更多信息,请参阅 unidep pip -h

usage: unidep pip [-h] [-f FILE] [-v]
                  [--platform {linux-64,linux-aarch64,linux-ppc64le,osx-64,osx-arm64,win-64}]
                  [--skip-dependency SKIP_DEPENDENCY]
                  [--ignore-pin IGNORE_PIN] [--overwrite-pin OVERWRITE_PIN]
                  [--separator SEPARATOR]

Get the pip requirements for the current platform only. Example usage: `unidep
pip --file folder1 --file folder2/requirements.yaml --separator ' ' --platform
linux-64` to extract all the pip dependencies specific to the linux-64
platform. Note that the `--file` argument can be used multiple times to
specify multiple `requirements.yaml` or `pyproject.toml` files and that --file
can also be a folder that contains a `requirements.yaml` or `pyproject.toml`
file.

options:
  -h, --help            show this help message and exit
  -f FILE, --file FILE  The `requirements.yaml` or `pyproject.toml` file to
                        parse, or folder that contains that file, by default
                        `.`
  -v, --verbose         Print verbose output
  --platform {linux-64,linux-aarch64,linux-ppc64le,osx-64,osx-arm64,win-64}, -p {linux-64,linux-aarch64,linux-ppc64le,osx-64,osx-arm64,win-64}
                        The platform(s) to get the requirements for. Multiple
                        platforms can be specified. By default, the current
                        platform (`linux-64`) is used.
  --skip-dependency SKIP_DEPENDENCY
                        Skip installing a specific dependency that is in one
                        of the `requirements.yaml` or `pyproject.toml` files.
                        This option can be used multiple times, each time
                        specifying a different package to skip. For example,
                        use `--skip-dependency pandas` to skip installing
                        pandas.
  --ignore-pin IGNORE_PIN
                        Ignore the version pin for a specific package, e.g.,
                        `--ignore-pin numpy`. This option can be repeated to
                        ignore multiple packages.
  --overwrite-pin OVERWRITE_PIN
                        Overwrite the version pin for a specific package,
                        e.g., `--overwrite-pin 'numpy=1.19.2'`. This option
                        can be repeated to overwrite the pins of multiple
                        packages.
  --separator SEPARATOR
                        The separator between the dependencies, by default ` `

unidep conda

requirements.yaml 文件上使用 unidep conda 并输出当前平台上的 conda 可安装依赖项(默认)。有关更多信息,请参阅 unidep conda -h

usage: unidep conda [-h] [-f FILE] [-v]
                    [--platform {linux-64,linux-aarch64,linux-ppc64le,osx-64,osx-arm64,win-64}]
                    [--skip-dependency SKIP_DEPENDENCY]
                    [--ignore-pin IGNORE_PIN] [--overwrite-pin OVERWRITE_PIN]
                    [--separator SEPARATOR]

Get the conda requirements for the current platform only. Example usage:
`unidep conda --file folder1 --file folder2/requirements.yaml --separator ' '
--platform linux-64` to extract all the conda dependencies specific to the
linux-64 platform. Note that the `--file` argument can be used multiple times
to specify multiple `requirements.yaml` or `pyproject.toml` files and that
--file can also be a folder that contains a `requirements.yaml` or
`pyproject.toml` file.

options:
  -h, --help            show this help message and exit
  -f FILE, --file FILE  The `requirements.yaml` or `pyproject.toml` file to
                        parse, or folder that contains that file, by default
                        `.`
  -v, --verbose         Print verbose output
  --platform {linux-64,linux-aarch64,linux-ppc64le,osx-64,osx-arm64,win-64}, -p {linux-64,linux-aarch64,linux-ppc64le,osx-64,osx-arm64,win-64}
                        The platform(s) to get the requirements for. Multiple
                        platforms can be specified. By default, the current
                        platform (`linux-64`) is used.
  --skip-dependency SKIP_DEPENDENCY
                        Skip installing a specific dependency that is in one
                        of the `requirements.yaml` or `pyproject.toml` files.
                        This option can be used multiple times, each time
                        specifying a different package to skip. For example,
                        use `--skip-dependency pandas` to skip installing
                        pandas.
  --ignore-pin IGNORE_PIN
                        Ignore the version pin for a specific package, e.g.,
                        `--ignore-pin numpy`. This option can be repeated to
                        ignore multiple packages.
  --overwrite-pin OVERWRITE_PIN
                        Overwrite the version pin for a specific package,
                        e.g., `--overwrite-pin 'numpy=1.19.2'`. This option
                        can be repeated to overwrite the pins of multiple
                        packages.
  --separator SEPARATOR
                        The separator between the dependencies, by default ` `

❓ 常见问题解答

以下是我们被用户询问过的问题列表,或者我们希望帮助用户避免的潜在陷阱

Q: 何时使用 UniDep?

A: UniDep 特别适用于使用单个命令设置需要 Python 以及非 Python 依赖项(例如 CUDA、编译器等)的完整开发环境。

在研究、数据科学、机器人学、AI 和 ML 项目等领域,通常从本地克隆的 Git 仓库中工作。

设置完整开发环境可能很痛苦,特别是如果您需要安装非 Python 依赖项,如编译器、低级数值库或 CUDA(幸运的是 Conda 包含所有这些)。通常,针对每个 OS 和相应的包管理器(如 aptbrewyumwinget 等)的说明都不同。

使用UniDep,您可以在单个文件中指定所有Pip和Conda依赖项。要在新机器上设置环境,只需安装Conda(我们推荐micromamba)并在项目目录中运行pip install unidep; unidep install-all -e,即可安装所有依赖项并在当前Conda环境中以可编辑模式安装本地包。

对于可完全重现的环境,您可以运行unidep conda-lock来生成conda-lock.yml文件。然后,运行conda env create -f conda-lock.yml -n myenv来创建一个新的Conda环境,包含所有第三方依赖项。最后,运行unidep install-all -e --no-dependencies来以可编辑模式安装所有本地包。

如果您不希望使用Conda,可以在使用UniDep的项目上简单地运行pip install -e .。您需要自行安装非Python依赖项,但它们将列在requirements.yaml文件中。

总之,如果您

  • 喜欢使用conda安装包,但仍然希望您的包能够通过pip安装。
  • 厌倦了同步Pip要求(requirements.txt)和Conda要求(environment.yaml)。
  • 想要一个低成本的全面开发环境设置。

Q: 只给我看一个完整的示例!

A: 查看示例文件夹example

Q: UniDep 在野外的用途?

A: 当在包含多个依赖项目的单一代码库中使用UniDep时,它特别出色,但由于这些通常是私有的,我们无法分享它们。

然而,一个公开的单个包示例是home-assistant-streamdeck-yaml。这是一个Python包,允许从通过USB连接到例如Raspberry Pi的Elgato Stream Deck与Home Assistant交互。它需要一些系统依赖项(例如,libusbhidapi),通常使用aptbrew安装。在README.md中展示了Linux、MacOS和Windows上非Conda安装的不同安装说明,但使用UniDep,我们可以在所有平台上使用unidep install .。它是通过pyproject.toml完全配置的。2个Dockerfile展示了使用UniDep的2种不同方式

  1. Dockerfile.locked:安装conda-lock.yml(由unidep conda-lock生成)然后pip install .安装本地包。
  2. Dockerfile.latest:使用unidep install .安装所有依赖项,首先使用conda,然后pip,最后安装本地包。

Q: 这与 conda/mamba/pip 有何不同?

A: UniDep在底层使用pip和conda安装依赖项,但它不是它们的替代品。UniDep将打印其运行的命令,因此您可以确切地看到它在做什么。

Q: 我发现了一个使用 unidep 的项目,现在怎么办?

A: 您可以使用pip install像安装其他任何Python包一样安装它。然而,要充分利用UniDep的功能,请克隆存储库并在项目目录中运行unidep install-all -e。这将在当前Conda环境中以可编辑模式安装所有依赖项。

Q: 如何处理不使用 UniDep 的本地依赖?

A: 您可以在requirements.yamlpyproject.toml文件中使用local_dependencies字段来指定本地依赖项。但是,如果本地依赖项不是由UniDep管理的,它将跳过安装其依赖项!

为了包含所有依赖项,可以将包转换为使用UniDep(🏆),或者维护一个单独的requirements.yaml文件,例如,对于一个名为foo的包,创建foo-requirements.yaml

dependencies:
  # List the dependencies of foo here
  - numpy
  - scipy
  - matplotlib
  - bar
local_dependencies:
  - ./path/to/foo  # This is the path to the package

然后,在依赖于foo的包的requirements.yamlpyproject.toml文件中,将foo-requirements.yaml列为一个本地依赖项

local_dependencies:
  - ./path/to/foo-requirements.yaml

Q: Conda 不是已经可以这样做了吗?

A:并不完全是这样。conda确实可以通过environment.yaml文件安装conda和pip依赖项,但反过来则不行。pip不能从environment.yaml文件中安装pip依赖项。这意味着,如果您希望您的包可以通过pip install -e .安装并且支持conda,您需要维护两个独立的文件:environment.yamlrequirements.txt(或者在pyproject.tomlsetup.py中指定这些依赖项)。

Q: conda-lockunidep conda-lock 之间有什么区别?

A: conda-lock是一个独立的工具,它可以从environment.yaml文件创建一个conda-lock.yml文件。另一方面,unidep conda-lock是UniDep工具中的一个命令,它也可以生成一个conda-lock.yml文件(利用conda-lock),但它是从一个或多个requirements.yamlpyproject.toml文件中生成的。当管理多个依赖项目(例如,在monorepo中)时,unidep conda-lock的一个独特功能是它能够为每个requirements.yamlpyproject.toml文件创建一个一致的conda-lock.yml文件,确保与全局conda-lock.yml文件的一致性。这个功能在独立的conda-lock工具中不可用。

Q: hatch-conda / pdm-condaunidep 之间有什么区别?

A: hatch-condahatch的一个插件,它将conda环境集成到hatch中。一个主要区别是,hatch-conda将conda和pip依赖项分开,选择使用conda或pip安装包。这导致conda成为一个硬性要求,例如,如果为conda指定了numba,则无法使用pip安装,尽管它在PyPI上有可用性。

相比之下,UniDep不需要conda。没有conda,它仍然可以安装PyPI上可用的任何依赖项(例如,numba既可以通过conda也可以通过pip安装)。然而,没有conda,UniDep将不会安装仅限于conda的依赖项。这些特定于conda的依赖项通常可以通过其他包管理器(如aptbrewyum)安装,或者通过源码构建。

另一个关键区别是,hatch-conda管理Hatch环境,而unidep可以在当前的Python环境中安装Pip依赖项(venv、Conda、Hatch等),然而,为了最优地使用UniDep,我们建议使用conda环境来额外安装非Python依赖项。

hatch-conda类似,unidep也集成了Hatchling,但它的工作方式略有不同。

A: pdm-condapdm的一个插件,旨在方便将conda环境与pdm结合使用。与hatch-conda类似,pdm-conda选择使用conda或pip安装包。它与pdm紧密集成,主要允许在pdm的锁文件(pdm.lock)中包含conda包。然而,pdm-conda缺乏广泛的跨平台支持。例如,当使用pdm-conda添加一个如Numba这样的包时,它会锁定到当前平台(例如,osx-arm64),而不提供为其他平台(如linux64)指定兼容性的灵活性。相比之下,UniDep允许跨平台兼容性,使用户能够指定多个平台的依赖项。目前,UniDep不支持pdm,但它支持Hatchling和Setuptools。

UniDep凭借其额外的功能,在

hatch-conda

中都脱颖而出,尤其是对于单仓库项目和跨多个操作系统的项目非常有益。例如

  1. conda锁文件:为所有软件包创建conda-lock.yml文件,每个软件包都有一致的子锁文件。
  2. CLI工具:提供如unidep install-all -e这样的工具,该工具将首先使用conda安装多个本地项目(例如,在单仓库中)及其所有依赖项,然后使用pip安装剩余的依赖项,最后以可编辑模式使用pip安装本地依赖项。
  3. conda环境文件:可以通过组合多个requirements.yamlpyproject.toml文件中的依赖项来创建标准的condaenvironment.yaml文件。
  4. 平台特定依赖项:允许指定特定平台的依赖项(例如,linux64、osx-arm64),增强跨平台兼容性。

:hammer_and_wrench: 故障排除

pip install 失败,出现 FileNotFoundError

当使用在requirements.yaml文件中包含local_dependencies: [../not/current/dir]的项目时

local_dependencies:
  # File in a different directory than the pyproject.toml file
  - ../common-requirements.yaml

当使用小于22.0版本的pip时,可能会遇到如下错误

$ pip install /path/to/your/project/using/unidep
  ...
  File "/usr/lib/python3.8/pathlib.py", line 1222, in open
    return io.open(self, mode, buffering, encoding, errors, newline,
  File "/usr/lib/python3.8/pathlib.py", line 1078, in _opener
    return self._accessor.open(self, flags, mode)
FileNotFoundError: [Errno 2] No such file or directory: '/tmp/common-requirements.yaml'

解决方案是将pip升级到22.0或更高版本

pip install --upgrade pip

:warning: 局限性

  • 以conda为中心:最适合conda环境。然而,请注意,安装使用UniDep的软件包不需要有conda。
  • 仅适用于setuptools和Hatchling:目前仅适用于setuptools和Hatchling,不适用于flit、poetry或其他构建系统。如果您想看到对其他构建系统的支持,请提交一个问题。
  • 平台选择器中没有逻辑运算符,也没有Python选择器

今天尝试使用unidep以简化跨多个项目管理您的conda环境依赖项的方法!🎉👏

项目详情


下载文件

下载适合您平台的文件。如果您不确定要选择哪个,请了解有关安装软件包的更多信息。

源代码分发

unidep-0.63.2.tar.gz (98.7 kB 查看哈希值)

上传时间 源代码

构建分发

unidep-0.63.2-py3-none-any.whl (59.5 kB 查看哈希值)

上传时间 Python 3

由以下支持

AWSAWS云计算和安全赞助商DatadogDatadog监控FastlyFastlyCDNGoogleGoogle下载分析MicrosoftMicrosoftPSF赞助商PingdomPingdom监控SentrySentry错误日志StatusPageStatusPage状态页面