Conda
Recipes and snippets for Conda, the open source package and environment management system widely used with Python, based on a tour of Conda from the command line.
Getting Miniconda
Just in case you ever need a convenience script to download Miniconda, in this case for Linux…
Resources
Common Issues
Using Conda inside a shell script
TLDR; insert eval "$(conda shell.bash hook)"
into the header of your (Bash) script following option (3). Option (1) is good too but requires the user (person running the script) to correctly use source
or .
where (1) works when the user executes the script via bash <my_script.sh>
.
The conda activate
command may not work inside a shell script due to the way shell scripts handle environment variables. When you run a shell script, it spawns a new shell, and any changes to the environment (like activating a conda environment) are local to that shell and do not affect the parent shell or any other shells.
There are a few ways to make conda activate
work inside a shell script:
-
Use
source
or.
beforeconda activate
: This is the most common way to makeconda activate
work in a shell script. Thesource
command or.
(dot) operator tells the shell to read and execute commands from the file in the current shell environment, rather than spawning a new shell. Here’s an example:Replace
/home/username/miniconda3/bin/activate
with the path to your conda’sactivate
script, and replacemyenv
with the name of your conda environment Source 4. -
Use
conda run
: Theconda run
command allows you to run a command in a specific conda environment. It’s not exactly the same as activating the environment, but it can be used to run a command in a specific environment without having to activate the environment first:Replace
myenv
with the name of your conda environment, and replacemyscript.py
with the command you want to run Source 5. -
Use
eval
withconda shell.bash hook
: Theconda shell.bash hook
command generates a script that sets up the conda environment for the bash shell. Theeval
command can execute this script in the current shell:Replace
myenv
with the name of your conda environment Source 22.
Remember that the conda activate
command only works in conda version 4.4 and later. If you’re using an older version of conda, you might need to use source activate
on Linux and macOS, or activate
on Windows instead Source 0.
Common Conda Commands
You can find out what Conda - in my case Miniconda - is capable of by executing conda --help
at the command line. You’ll get a list of commands and we’ll take them as they come. I frequently use the long-form of arguments here to make things more self-evident.
clean - Remove unused packages and caches
This is a useful command which will free space on the filesystem by deleting packages or the cached artifacts of packages (like tarballs) that are left over after their installation.
For example, if I run conda clean --dry-run --tarballs
on my machine, I see the following output
Cache location: /home/anil/miniconda3/pkgs
Will remove the following tarballs:
/home/anil/miniconda3/pkgs
--------------------------
ca-certificates-2022.3.29-h06a4308_1.conda 122 KB
sqlite-3.39.2-h4ff8645_0.tar.bz2 1.5 MB
numpy-1.23.1-py38h6c91a56_0.conda 11 KB
xz-5.2.5-h516909a_1.tar.bz2 343 KB
blas-1.0-mkl.tar.bz2 1 KB
zstd-1.5.2-h6239696_4.tar.bz2 448 KB
pytorch-mutex-1.0-cuda.tar.bz2 3 KB
torchvision-0.12.0-py38_cu113.tar.bz2 27.7 MB
libstdcxx-ng-9.3.0-hd4cf53a_17.conda 3.1 MB
cffi-1.15.1-py38h4a40e3a_0.tar.bz2 229 KB
_libgcc_mutex-0.1-conda_forge.tar.bz2 3 KB
_libgcc_mutex-0.1-main.conda 3 KB
libwebp-base-1.2.3-h166bdaf_2.tar.bz2 392 KB
...
---------------------------------------------------
Total: 2.35 GB
DryRunExit: Dry run. Exiting.
A whopping 2.35 GB would be freed up if I deleted the tarballs that I no longer need for function of the Python packages in my environments.
The output from conda clean --dry-run --all
is identical.
Instead, if I check what can be cleaned up from package caches, via the command conda clean --dry-run --packages
I see that 164.8 MB are free-able via removal of unused packages from writable package caches:
WARNING: /home/anil/.conda/pkgs does not exist
Cache location: /home/anil/miniconda3/pkgs
Will remove the following packages:
/home/anil/miniconda3/pkgs
--------------------------
libcblas-3.9.0-12_linux64_mkl 42 KB
giflib-5.2.1-h36c2ea0_2 312 KB
libblas-3.9.0-12_linux64_mkl 43 KB
numpy-1.23.1-py38h6c91a56_0 29 KB
openjpeg-2.4.0-hb52868f_1 1.5 MB
libzlib-1.2.12-h166bdaf_2 127 KB
_openmp_mutex-4.5-1_gnu 93 KB
pyopenssl-22.0.0-pyhd8ed1ab_0 246 KB
numpy-base-1.23.1-py38ha15fc14_0 29.4 MB
...
numpy-1.23.3-py38h3a7f9d9_0 29.4 MB
freetype-2.10.4-hca18f0e_2 2.8 MB
---------------------------------------------------
Total: 164.8 MB
Finally, I have no index cache to free up as noted by the fact that conda clean --dry-run --index-cache
returns nothing.
compare - Compare packages between conda environments
The usage of conda compare
is
Note that this takes the required positional argument file
, which is the path to the environment file that is to be compared against. This constrains you to comparing a target environment passed either by --name
or --prefix
against an environment YAML file.
Comparing Two Environments Directly
What if you want to compare if two environments on your machine are identical? You have to export one of these environments to a YAML and compare the other against it.
Let’s assume we have two environments bleep
and blorp
which we have created and installed a few things into…
We have the following in bleep
…and we have the following in blorp
# requirement_blorp.txt
librosa
soundfile
sox
kaldiio
scipy
g2p-en
pydub
matplotlib
# these weren't in bleep
numpy
black==19.10b0
wandb
Now let’s say we want to compare the two against each other. We can use a small snippet like the following which
- activates the
base
conda environment (just so we get used to using the explicit references to environments via names or prefixes) - makes
./temp/
- exports the
blorp
conda environment to./temp/blorp.yaml
- compares the target conda environment
bleep
to blorp via./temp/blorp.yaml
- deletes
./temp/blorp.yaml
- deletes
./temp
if it is empty (or else tells you what else has been left lying around in there)
The output we get from running conda compare --name bleep ./temp/blorp.yml
is
attrs not found
black not found
docker-pycreds not found
gitdb not found
gitpython not found
pathspec not found
pathtools not found
promise not found
protobuf not found
psutil not found
pyyaml not found
sentry-sdk not found
setproctitle not found
shortuuid not found
smmap not found
toml not found
typed-ast not found
wandb not found
If we were to run it the other way round, comparing an export of bleep
to blorp
as the target environment via the following sequence of commands
We get the output
Success. All the packages in the specification file are present in the environment with matching version and build string.
Be aware that conda will return success if all the packages in the spec. file are present in the target environment with the matching version and build string, including if there are additional packages in the target environment, as is clearly the case in the above example. You can see this another way by running conda activate bleep && pip list | wc -l
which returns 59
against conda activate blorp && pip list | wc -l
which returns 77
.
If you get the rather scary warning that pip’s dependency resolver does not currently take into account all the packages that are installed check out What does the error message about pip –use-feature=2020-resolver mean?.
install - Installs a list of packages into a specified conda environment
Note the option for using copies when installing packages instead of hard- or soft-linking.
Package Linking and Install-time Options:
--copy Install all packages using copies instead of hard- or soft-linking.
-m, --mkdir Create the environment directory if necessary.
--clobber Allow clobbering of overlapping file paths within packages, and suppress related warnings.