Run scripts with dependencies#
conda-exec can run Python scripts that declare their dependencies inline using the PEP 723 metadata format.
Conda-only dependencies#
Use the [tool.conda] table to declare conda packages:
# /// script
# [tool.conda]
# channels = ["conda-forge", "bioconda"]
# dependencies = ["samtools>=1.19", "htslib"]
# ///
conda exec script.py
PyPI dependencies#
Use the standard PEP 723 dependencies field for PyPI packages:
# /// script
# dependencies = ["requests>=2.31", "rich"]
# ///
conda exec script.py
Warning
PyPI dependencies require conda-pypi to be installed. Without it, conda-exec cannot resolve PyPI packages and will exit with an error.
conda-exec adds the conda-pypi channel automatically.
Install conda-pypi if you haven’t already:
conda install -n base conda-pypi
Mixed conda and PyPI dependencies#
Combine both in a single script:
# /// script
# requires-python = ">=3.12"
# dependencies = ["requests"]
#
# [tool.conda]
# channels = ["conda-forge", "bioconda"]
# dependencies = ["samtools>=1.19"]
# ///
Both conda and PyPI packages are resolved together in a single environment
solve. The conda-pypi channel converts PyPI wheels into conda packages,
so the rattler solver handles everything in one pass.
Pin the Python version#
Use requires-python to constrain which Python version is installed:
# /// script
# requires-python = ">=3.12"
# dependencies = ["click"]
# ///
This adds a python >=3.12 spec to the environment solve.
Add extra dependencies from the CLI#
Override or extend a script’s dependencies from the command line:
conda exec --with numpy -c defaults script.py
CLI extras (--with and -c) are merged with the script’s declared
dependencies.
Scripts without metadata#
Note
Scripts without a # /// script block run directly with the current
Python interpreter. No environment is created, and no packages are installed.
Scripts without metadata are passed through as-is:
conda exec hello.py
Make scripts directly executable#
Add a shebang line to run scripts without typing conda exec or ce:
#!/usr/bin/env ce
# /// script
# [tool.conda]
# channels = ["conda-forge"]
# dependencies = ["numpy"]
# ///
import numpy as np
print(np.random.default_rng().random(5))
chmod +x demo.py
./demo.py
The ce standalone command is the recommended shebang target because it
works on all platforms. Using conda exec in a shebang does not work
because the kernel cannot split multi-word interpreter arguments portably.
Note
On macOS and recent Linux kernels, #!/usr/bin/env -S conda exec works
via the -S (split string) flag, but this is not portable to all systems.
Use #!/usr/bin/env ce for maximum compatibility.
Force re-creation#
If the cached script environment is stale:
conda exec --refresh script.py