PyPI dependencies#
This guide walks through adding PyPI packages to a conda-workspaces project, including versioned dependencies, editable local packages, and what to install for everything to work.
Manifest compatibility with pixi#
The [pypi-dependencies] table uses the same syntax as
pixi, so manifests are portable between the two
tools. The underlying implementation is different: pixi resolves PyPI
packages with its own built-in solver (uv), while conda-workspaces
delegates to conda-pypi and conda-rattler-solver through conda’s
plugin system.
Prerequisites#
PyPI dependency support requires two conda packages and a channel configuration:
conda install conda-pypi conda-rattler-solver
conda config --set solver rattler
conda config --append channels conda-pypi
conda-pypi translates PyPI package names to their conda equivalents and handles wheel extraction and editable installs.
conda-rattler-solver is the solver backend that can resolve conda and PyPI packages together in a single pass. Since conda-pypi 0.9.0 it is no longer installed automatically, so you need to install it explicitly.
The conda-pypi channel on conda.anaconda.org makes pure Python
packages from PyPI available as conda packages. It uses sharded
repodata, which requires the rattler solver to read. Without this
channel, the solver has no source for PyPI-originated packages.
If conda-pypi or conda-rattler-solver is missing, conda workspace install prints a warning and skips PyPI dependencies.
See also
These tools build on the conda plugin architecture defined in
CEP 2 (plugin
architecture proposal) and
CEP 4 (plugin
mechanism implementation). The solver backend plugin hook that
conda-rattler-solver uses was introduced by
CEP 3
(pluggable solver backends, originally for conda-libmamba-solver).
conda-pypi also registers a package extractor plugin that teaches
conda how to extract .whl archives, so wheels are installed through
the same transaction pipeline as .conda packages.
Adding versioned PyPI dependencies#
Declare PyPI dependencies alongside your conda dependencies in the manifest:
[dependencies]
python = ">=3.10"
numpy = ">=1.24"
[pypi-dependencies]
httpx = ">=0.27"
pydantic = ">=2.0,<3"
PyPI package names are translated to their conda equivalents via the grayskull mapping and merged into the same solver call as conda dependencies. The solver resolves everything together, so conda and PyPI packages cannot conflict.
Install as usual:
conda workspace install
Extras#
PyPI extras are supported with square-bracket syntax:
[pypi-dependencies]
httpx = { version = ">=0.27", extras = ["http2"] }
Per-feature PyPI dependencies#
Just like conda dependencies, PyPI dependencies can be scoped to a feature:
[feature.test.pypi-dependencies]
pytest-httpx = ">=0.30"
[environments]
default = []
test = { features = ["test"] }
Editable local packages#
For local Python packages under active development, use a path
dependency with editable = true:
[pypi-dependencies]
my-project = { path = ".", editable = true }
This installs the package in editable (development) mode so that
changes to the source code take effect immediately without
reinstalling. conda-pypi builds the package into a .conda archive
using PEP 517 and installs it into the environment prefix.
Path dependencies can also point to subdirectories in a monorepo:
[pypi-dependencies]
core = { path = "packages/core", editable = true }
api = { path = "packages/api", editable = true }
Editable and path dependencies are handled separately from versioned PyPI dependencies. They are built and installed after the main solver completes, so they do not participate in dependency resolution. Make sure any transitive dependencies your local package needs are declared as conda or versioned PyPI dependencies in the manifest.
Git and URL dependencies#
You can also install packages directly from git repositories or URLs:
[pypi-dependencies]
my-fork = { git = "https://github.com/user/project.git", branch = "main" }
some-wheel = { url = "https://example.com/pkg-1.0-py3-none-any.whl" }
Like editable installs, these are built post-solve by conda-pypi and do not participate in the solver pass.
Troubleshooting#
“conda-pypi is not installed”#
Install it:
conda install conda-pypi
“conda-rattler-solver is not installed”#
Since conda-pypi 0.9.0, the solver backend is a separate package:
conda install conda-rattler-solver
Solve failures with PyPI packages#
If the solver cannot find a PyPI package, check that:
The
conda-pypichannel is in your channel list. Add it withconda config --append channels conda-pypior include it in your manifest’schannelslist.The solver is set to
rattler(conda config --set solver rattler). Theconda-pypichannel uses sharded repodata that only the rattler solver can read.The package name is spelled correctly (PyPI names are case-insensitive but conda names use lowercase and hyphens).
The version constraint is satisfiable.
Next steps#
Features: PyPI dependencies for the full reference on supported fields
Configuration for all manifest options
Your first project for a complete walkthrough