Architecture#

Overview#

conda-exec is a conda plugin that enables ephemeral package execution. It creates cached, isolated environments and runs tools from them without modifying the user’s PATH or global state.

In addition to the conda exec subcommand, conda-exec provides a standalone ce command. This is a console script entry point (ce = "conda_exec.main:main" in pyproject.toml) that creates its own ArgumentParser with prog="ce" and calls the same configure_parser() and execute() functions as conda exec. The relationship mirrors how uvx is a standalone alias for uv tool run: ce ruff check . is equivalent to conda exec ruff check ., but shorter to type and usable without conda’s plugin system loaded.

Tip

The ce command bypasses conda’s plugin loading, so it starts faster than conda exec. If you use conda-exec frequently, ce is the recommended entry point.

Flow#

Tool execution#

        flowchart TD
    A["<b>conda exec ruff check .</b>"] --> B["<b>plugin.py</b><br>Register exec subcommand"]
    B --> C["<b>cli.py</b><br>Parse args, dispatch to handler"]
    C --> D["<b>execute.py</b><br>Extract tool name, build specs list"]
    D --> E{"<b>cache.py</b><br>Compute cache key, check cache"}
    E -- cache hit --> F["<b>binaries.py</b><br>Find binary in prefix"]
    E -- cache miss --> G["<b>Solver + transaction</b><br>Create env in ~/.conda/exec/envs/"]
    G --> F
    F --> H["<b>run.py</b><br>subprocess.run with PATH prepend<br>(or full activation with --activate)"]
    H --> I(["Exit code forwarded"])
    

Script execution#

When the tool argument is a path to an existing file, conda-exec switches to script mode:

        flowchart TD
    A["<b>conda exec script.py</b>"] --> B["<b>execute.py</b><br>Path(tool).is_file() → script mode"]
    B --> C["<b>script.py</b><br>Parse PEP 723 metadata block"]
    C --> D{Has dependencies?}
    D -- no metadata --> E["<b>run_script_directly</b><br>Run with current Python"]
    D -- has deps --> F{Has PyPI deps?}
    F -- yes --> G{"conda-pypi available?"}
    G -- no --> H(["Error: conda-pypi required"])
    G -- yes --> I["Add conda-pypi channel"]
    F -- no --> I
    I --> J["<b>cache.py</b><br>Compute script cache key"]
    J --> K{"Cache exists?"}
    K -- hit --> L["<b>binaries.py</b><br>Find python in prefix"]
    K -- miss --> M["<b>Solver + transaction</b><br>Resolve conda + PyPI deps together"]
    M --> L
    L --> N["<b>run.py</b><br>Run python script.py in prefix"]
    N --> O(["Exit code forwarded"])
    

Why not conda run?#

conda run uses wrap_subprocess_call() which generates activation shell scripts, captures output by default, and adds overhead. Most CLI tools don’t need full conda activation. Direct subprocess.run with PATH prepended is simpler, faster, and avoids output-capture pitfalls.

Why not extend conda-global?#

conda-global manages persistent, user-facing tool installations with PATH integration via trampolines. conda-exec manages ephemeral cached environments for one-shot execution. They are two distinct models that should not share state or environment prefixes.

Why require conda-rattler-solver?#

Ephemeral execution must be fast. The rattler solver (via resolvo) is significantly faster than classic libmamba for cold solves. Since conda-express (cx) already ships conda-rattler-solver as the default, and conda-exec is designed to ship as part of that distribution, this is a natural requirement.

Part of the conda-express ecosystem#

conda-exec is one of several plugins that ship with conda-express (cx), a single-binary conda distribution:

Plugin

Purpose

conda-rattler-solver

Modern solver backend

conda-spawn

Subshell-based activation

conda-self

Self-update

conda-workspaces

Multi-environment workspaces

conda-global

Persistent global tools

conda-completion

Shell tab completion

conda-pypi

PyPI interop layer

conda-exec

Ephemeral package execution