Package Management#
Python environment#
Python has become a standard tool in power systems engineering, offering extensive capabilities for system analysis, optimization, and data processing. Its widespread adoption in the field stems from both its accessibility and its rich ecosystem of specialized libraries that can be combined to solve complex problems.
When developing power system applications, you will typically work with multiple specialized packages; some for numerical computations, others for power system modeling, and perhaps others for visualization or data analysis. These packages often have specific version requirements, especially when dealing with industry-standard tools or research implementations.
This is where Python environments become essential. An environment is an isolated workspace that allows you to maintain different configurations of packages for different projects. For instance, you might have one environment configured for power system stability analysis with an older version of numerical solvers, and another set up for machine learning applications in load forecasting that needs a newer version of the same solver. The solver is called a “dependency” of the project.
Python provides a package manager called pip
that makes it easy
to install and manage dependencies. pip
works well for small projects but sees
difficulties when managing complex projects with binary (compiled library)
dependencies. Binary dependencies exist because they are compiled from source code
for specific operating systems and hardware architectures.
To solve the problem of binary dependencies, we can use a package manager called
conda
. conda
is a package manager that is more robust and handles binary
dependencies better than pip
.
Anaconda, conda, and miniconda#
Here is some background.
Anaconda Inc. is a company that develops the Anaconda Distribution (“Anaconda” in short). It is a collection of packages for Python and R.
Central to the Anaconda Distribution is the
conda
tool for package management.Miniconda is a free and slim version of Anaconda. It is a bootstrap (self-starting) version of Anaconda that provides only
conda
, Python, and a small number of packages likepip
.
conda-forge#
To distribute packages on Anaconda, one needs to create an account and publish the
package under that account (called “channel”). It is sometimes difficult locate the channel
and the correct version of the package. Therefore, conda-forge
is a single, community-managed
channel that contains all the packages that are available for conda
.
mamba, and mini-forge#
conda
is great but not perfect. Since conda
is written in Python, its speed is a bottleneck when
resolving many dependencies with multiple versions. mamba
, as the name suggests, is a fast, concurrent
package manager that is built on top of conda
and pip
. It is a drop-in replacement for conda
and is much faster.
In the following, we may use mamba
and conda
interchangeably as they are
drop-in replacements of each other. If you want speed as much as I do, use mamba
.
pip and conda#
This section is useful if you already know pip
.
conda
is not entirely an alternative to pip
. Many packages can be installed
by either of them. Packages with significant binary dependencies (such
as NVIDIA CUDA) can be installed by conda
but not by pip
.
Some (probably less frequently used) packages can be installed
by pip
but not by conda
, because the authors haven’t published the package
to conda
.
conda
uses different package registries and
handle binary dependencies differently under the hood.
Using mamba to manage environments#
We recommend using conda
/mamba
to manage environments. This is helpful on
Windows, Linux (including WSL), and macOS to avoid headaches down the road.
Installation#
As an example, we will install miniforge
, which provides mamba
and conda
.
Miniforge
can be found at conda-forge/miniforge.
To install miniforge
in WSL, follow the installation instruction at
https://github.com/conda-forge/miniforge?tab=readme-ov-file#unix-like-platforms-macos–linux.
In a nutshell, there are two steps:
Download the installer script.
wget "https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-$(uname)-$(uname -m).sh"
Run the installer script.
bash Miniforge3-$(uname)-$(uname -m).sh
The installer script will ask you to review the license terms. Press Enter to
continue, scroll down to the end, type yes
and press enter to continue.
Next, the installer will ask you other questions such as the installation directory. If you are unsure, press Enter to accept the default.
You will wait a few minutes for the installation to complete. At the end, the
installer will ask if you want to automatically initialize conda. The default
option is no
, but for convenience, we recommend typing yes
to continue.
Once installed, restart your shell by closing and reopening your WSL terminal. A change will appear in your shell prompt:
(base) User@Host:~$
The (base)
indicates that you are now operating in the base
environment set
by conda. Operating in a specific environment will let you gain access to the
packages in that environment, on top of system-wide packages.
Creating environments#
We will explain environment by example. Let’s create a new environment called
pct
and install python=3.12
in it.
(base) User@Host:~$ mamba create -n pct python=3.12
The -n
flag tells mamba
to create a new environment called pct
. The python=3.12
specifies that we want to install Python 3.12 in the new environment. You can
specify Python packages alongside python=3.12
. The output may look like
__ __ __ __
/ \ / \ / \ / \
/ \/ \/ \/ \
███████████████/ /██/ /██/ /██/ /████████████████████████
/ / \ / \ / \ / \ \____
/ / \_/ \_/ \_/ \ o \__,
/ _/ \_____/ `
|/
███╗ ███╗ █████╗ ███╗ ███╗██████╗ █████╗
████╗ ████║██╔══██╗████╗ ████║██╔══██╗██╔══██╗
██╔████╔██║███████║██╔████╔██║██████╔╝███████║
██║╚██╔╝██║██╔══██║██║╚██╔╝██║██╔══██╗██╔══██║
██║ ╚═╝ ██║██║ ██║██║ ╚═╝ ██║██████╔╝██║ ██║
╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝╚═════╝ ╚═╝ ╚═╝
mamba (0.22.1) supported by @QuantStack
GitHub: https://github.com/mamba-org/mamba
Twitter: https://twitter.com/QuantStack
█████████████████████████████████████████████████████████████
Looking for: ['python=3.12']
conda-forge/linux-64 Using cache
conda-forge/noarch Using cache
Transaction
Prefix: /home/User/mambaforge/envs/pct
Updating specs:
- python=3.12
Package Version Build Channel Size
─────────────────────────────────────────────────────────────────────────────────────
Install:
─────────────────────────────────────────────────────────────────────────────────────
+ _libgcc_mutex 0.1 conda_forge conda-forge/linux-64 Cached
+ _openmp_mutex 4.5 2_gnu conda-forge/linux-64 Cached
+ bzip2 1.0.8 hd590300_5 conda-forge/linux-64 254kB
+ ca-certificates 2024.2.2 hbcca054_0 conda-forge/linux-64 Cached
+ ld_impl_linux-64 2.40 h55db66e_0 conda-forge/linux-64 713kB
+ libexpat 2.6.2 h59595ed_0 conda-forge/linux-64 74kB
+ libffi 3.4.2 h7f98852_5 conda-forge/linux-64 Cached
+ libgcc-ng 13.2.0 h77fa898_7 conda-forge/linux-64 776kB
+ libgomp 13.2.0 h77fa898_7 conda-forge/linux-64 422kB
+ libnsl 2.0.1 hd590300_0 conda-forge/linux-64 33kB
+ libsqlite 3.45.3 h2797004_0 conda-forge/linux-64 Cached
+ libuuid 2.38.1 h0b41bf4_0 conda-forge/linux-64 34kB
+ libxcrypt 4.4.36 hd590300_1 conda-forge/linux-64 100kB
+ libzlib 1.2.13 hd590300_5 conda-forge/linux-64 Cached
+ ncurses 6.5 h59595ed_0 conda-forge/linux-64 887kB
+ openssl 3.3.0 h4ab18f5_3 conda-forge/linux-64 3MB
+ pip 24.0 pyhd8ed1ab_0 conda-forge/noarch 1MB
+ python 3.12.3 hab00c5b_0_cpython conda-forge/linux-64 32MB
+ readline 8.2 h8228510_1 conda-forge/linux-64 Cached
+ setuptools 70.0.0 pyhd8ed1ab_0 conda-forge/noarch 483kB
+ tk 8.6.13 noxft_h4845f30_101 conda-forge/linux-64 3MB
+ tzdata 2024a h0c530f3_0 conda-forge/noarch 120kB
+ wheel 0.43.0 pyhd8ed1ab_1 conda-forge/noarch 58kB
+ xz 5.2.6 h166bdaf_0 conda-forge/linux-64 Cached
Summary:
Install: 24 packages
Total download: 44MB
─────────────────────────────────────────────────────────────────────────────────────
Confirm changes: [Y/n] y
libgomp 422.3kB @ 1.6MB/s 0.3s
libxcrypt 100.4kB @ 284.9kB/s 0.4s
ld_impl_linux-64 713.3kB @ 1.9MB/s 0.4s
wheel 58.0kB @ 138.6kB/s 0.1s
libgcc-ng 775.8kB @ 1.7MB/s 0.4s
bzip2 254.2kB @ 533.3kB/s 0.1s
libnsl 33.4kB @ 64.3kB/s 0.1s
tzdata 119.8kB @ 207.6kB/s 0.1s
ncurses 887.5kB @ 1.5MB/s 0.1s
openssl 2.9MB @ 4.6MB/s 0.6s
libuuid 33.6kB @ 52.6kB/s 0.1s
tk 3.3MB @ 5.1MB/s 0.4s
setuptools 483.0kB @ 668.8kB/s 0.1s
pip 1.4MB @ 1.8MB/s 0.2s
libexpat 73.7kB @ 76.7kB/s 0.3s
python 32.0MB @ 19.8MB/s 1.2s
Preparing transaction: done
Verifying transaction: done
Executing transaction: done
To activate this environment, use
$ mamba activate pct
To deactivate an active environment, use
$ mamba deactivate
The end of the output suggests that you have created but not yet activated the environment. Before activating the new environment, let’s check which Python interpreter can be found in the current env:
(base) User@Host:~$ which python
/home/User/mambaforge/bin/python
(base) User@Host:~$ python
Python 3.9.6 | packaged by conda-forge | (default, Jul 11 2021, 03:39:48)
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> exit()
(base) User@Host:~$
You can tell that the Python interpreter in base
is Python 3.9 on my machine.
It may differ on yours.
Next, let’s activate the new environment:
(base) User@Host:~$ mamba activate pct
(pct) User@Host:~$ which python
/home/User/mambaforge/envs/pct/bin/python
(pct) User@Host:~$ python
Python 3.12.3 | packaged by conda-forge | (main, Apr 15 2024, 18:38:13) [GCC 12.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> exit()
(base) User@Host:~$
You can tell the python
command now points to the Python in the pct
environment. The preamble of the Python interpreter indicates that you are using
the installed 3.12 version.
Exercise
Follow the same steps to create a new environment called
pct
and install Python 3.12 in it.Activate the environment, and check the Python version.
Deactivate the environment, and check the Python version again.
When to use conda
and pip
#
It is a good practice to avoid installing packages to the base
environment.
The base
environment is to provide the core libraries and dependencies for a
functional conda
installation. Installations to base
may lead to unexpected
behavior.
Instead, create a new environment for each project. Just remember to activate the environment before installing packages or running scripts.
We mentioned that a Python package may be installed by conda
or pip
. The
recommended practice is:
If a package is available for
conda
, install it viaconda
. This will satisfy a more complete set of dependencies.If a package is not available for
conda
, install it viapip
.
Installation with conda
#
There are a few commonly used commands for mamba
besides activate
and
deactivate
:
mamba install
: Install a package.mamba update
: Update a package.mamba remove
: Remove a package.mamba list
: List installed packages in the current environment.
Exercise
Activate the
pct
environment.Install
jupyter
viamamba
usingmamba install jupyter
. You will be prompted to confirm the installation. Typey
and pressEnter
. You can skip the confirmation withmamba install jupyter --yes
.Run
jupyter notebook
to start the Jupyter notebook. Follow the link to open the notebook in your web browser.Close the notebook program from the terminal by using
Ctrl-C
(holding down Ctrl and press C).Deactivate the
pct
environment to return tobase
.Run
jupyter notebook
again. You should see an error message, indicating thatjupyter
is not installed. Why?
Oftentimes, you will use conda search
to search for packages. For example,
mamba search jupyter
will search for jupyter
in the conda-forge
channel,
which the default channel for mamba. The search result may include multiple versions
of jupyter
.
Exercise with mamba list
It is useful to check what packages are installed in the current env.
Activate the
pct
environment.Run
mamba list
. You will see a rather long list of packages, although we only installedjupyter
. Other packages are the dependencies of Jupyter.
Installation with pip
#
pip
is the standard package manager for Python. In any mamba environment, if
Python is installed, pip
is installed. We discussed the reasons to prefer
mamba
over pip
. Occasionally, you will still use pip
.
The basic commands for pip
are:
pip install
: Install a package.pip remove
: Remove a package.pip list
: List installed packages in the current environment.
You can refer to pip documentation at https://pip.pypa.io/en/stable/cli/
Where does pip install packages?
pip
is a Python package, so it installs to the same environment that
contains the Python executable. This environment is often the active environment.
To confirm, run which python
and which pip
. Their paths should be the same.
If they are not the same, you will need to deactivate and activate the environment to fix environmental variables.
Published packages can be searched on the Python Package Index at
https://pypi.org/. There was a pip search
command, but unfortunately, it has
been disabled for security reasons.
To install a published package on pip
, use pip install <package>
.
To emphasize, if a package is available for conda
, install it via conda
. This will
satisfy a more complete set of dependencies.
Exercise: Installing pypower
Confirm that your pip is from the active environment.
Install
pypower
viapip
.Confirm that
pypower
is installed by running
python -c "import pypower; print(pypower)"
Installing a package from source#
Most of the time, you will install packages that has been published to PyPI or conda-forge. If you are experimenting with a package that has yet to be published, such as a personal project on GitHub, you will need to install from source.
Note
Not all Python repositories on GitHub are installable though. Some repos are meant for sharing scripts, not for distribution.
If a package contains setup.py
, you can install it from source by running
pip install .
in the root directory of the package. Note the .
at the end of
the command. It specifies the directory that contains setup.py
.
Developing a package#
Another use of pip
is to set up a developmental installation of a package.
This is helpful you want to modify the package and test your changes, without
having to reinstall the package.
To install a package in developmental mode, run pip install -e .
in the root
directory of the package. Also note the dot at the end. The option -e
means
“editable”.
(TODO: add multiple choice questions and exercise to test understanding)
Mixing conda and pip#
Now that you have installed jupyter
via mamba
and pypower
via pip
to the
same environment, both packages can be used in the same Python.
There is a possibility that you install two different versions of the same
packages to the same environment by using mamba
and pip
, respectively. This
is because the two package managers are not designed to fully interopate.
Installing two versions of the same package creates problems. You won’t be able
to tell which version is imported when you run a script. If you accidentally did
so, which means that you didn’t follow the mamba
first, and then pip
instructions, you will need to uninstall the package in both package
managers, make sure that you get a clean environment without the package, and
reinstall it using your desired package manager.
Having multiple versions of the same package can also happen when you have
installed a package, for example, andes
, using mamba
. Then, you
develop-installed andes
using pip
from source. This creates the same
problem. The solution is also to remove all of them and reinstall just one copy.
Mamba provides a command to list all installed packages in the current environment. Below is an example of the output; your list should look much longer.
mamba list
# packages in environment at /home/User/mambaforge/envs/pct:
#
# Name Version Build Channel
[TRUNCATED OUTPUT]
jupyter 1.0.0 pyhd8ed1ab_10 conda-forge
pypower 5.1.16 pypi_0 pypi
[TRUNCATED OUTPUT]
Scroll through it, you will see the Build
and Channel
columns
contain different information for jupyter
and pypower
. Since jupyter
is
installed via mamba
, mamba
then nows the channel and the build number.
pypower
is installed via pip
, so the Channel shows pypi
. You can use this
to tell which package manager installed the package.
System-wide packages#
Beside mamba/conda-installed packages, each Linux distribution also comes with at least one package manager.
The most popular one is apt
, which is the package manager for Debian-based
distributions. Ubuntu is a Debian-based distribution. We will discuss some very
basic usage of apt
.
Updating the package list#
Executing apt
requires superuser permission. On Ubuntu, you can update the
package list by running sudo apt update
. This will fetch the latest package
information from the repositories.
When done, it will show the number of packages available for upgrade.
Installing a package#
To install a package, use sudo apt install <package>
. For example, to install
the development tools
, use
sudo apt install build-essential
You can add the argument -y
to skip the confirmation.
build-essential
includes compilers and other development tools. When done, you
will have tools like gcc
, make
, g++
, etc. To check if the installation is
successful, run gcc -v
.
Packages installed via apt
are global packages. They are installed to the
system, not just to the current user.
Removing a package#
To remove a package, use sudo apt remove <package>
.
System-wide or local?#
You may have packages that are installed by both apt
and mamba
. We mentioned
that which
can be used to determine which interpreter is used when you run
python3
in a terminal.
Exercise
Open a new terminal. You should be in the (base) environment.
Find out which python3 it is.
Deactive the environment. Find out which python3 again. This time, it should point to a system-wide python3.