Lecture 23 - Dependency Management, Virtual Environments, and Containers
conda or piprenv (for R), or pipenv (for Python)conda (python and R): generate an environment.yml filepip (python only): generate a requirements.txt fileenvironment.yml (for conda)
conda env export -f environment.yml-f is a flag for “file”requirements.txt (for pip)
pip freeze | grep -v 'file://' > requirements.txtpip install -r requirements.txt-r is a flag for “requirements”environment.yml filescripts folder (but it won’t be shared with others)environment.yml fileenvironment.yml file, you can use the following command (you can create the file in any folder, e.g., your Desktop):name: qtm350
channels:
- defaults
dependencies:
- blas=1.0=openblas
- bottleneck=1.4.2=py312ha86b861_0
- brotli=1.0.9=h80987f9_8
- brotli-bin=1.0.9=h80987f9_8
- bzip2=1.0.8=h80987f9_6
- ca-certificates=2024.9.24=hca03da5_0
- contourpy=1.2.0=py312h48ca7d4_0
- cycler=0.11.0=pyhd3eb1b0_0
- expat=2.6.3=h313beb8_0
- fonttools=4.51.0=py312h80987f9_0
- freetype=2.12.1=h1192e45_0
- jpeg=9e=h80987f9_3
- kiwisolver=1.4.4=py312h313beb8_0
- lcms2=2.12=hba8e193_0
- lerc=3.0=hc377ac9_0
- libbrotlicommon=1.0.9=h80987f9_8
- libbrotlidec=1.0.9=h80987f9_8
- libbrotlienc=1.0.9=h80987f9_8
- libcxx=14.0.6=h848a8c0_0
- libdeflate=1.17=h80987f9_1
- libffi=3.4.4=hca03da5_1
- libgfortran=5.0.0=11_3_0_hca03da5_28
- libgfortran5=11.3.0=h009349e_28
- libopenblas=0.3.21=h269037a_0
- libpng=1.6.39=h80987f9_0
- libtiff=4.5.1=h313beb8_0
- libwebp-base=1.3.2=h80987f9_1
- llvm-openmp=14.0.6=hc6e5704_0
- lz4-c=1.9.4=h313beb8_1
- matplotlib=3.9.2=py312hca03da5_0
- matplotlib-base=3.9.2=py312h2df2da3_0
- ncurses=6.4=h313beb8_0
- numexpr=2.10.1=py312h5d9532f_0
- numpy=1.26.4=py312h7f4fdc5_0
- numpy-base=1.26.4=py312he047099_0
- openjpeg=2.5.2=h54b8e55_0
- openssl=3.0.15=h80987f9_0
- packaging=24.1=py312hca03da5_0
- pandas=2.2.2=py312hd77ebd4_0
- pillow=11.0.0=py312hfaf4e14_0
- pip=24.2=py312hca03da5_0
- pyparsing=3.2.0=py312hca03da5_0
- python=3.12.7=h99e199e_0
- python-dateutil=2.9.0post0=py312hca03da5_2
- python-tzdata=2023.3=pyhd3eb1b0_0
- pytz=2024.1=py312hca03da5_0
- readline=8.2=h1a28f6b_0
- setuptools=75.1.0=py312hca03da5_0
- six=1.16.0=pyhd3eb1b0_1
- sqlite=3.45.3=h80987f9_0
- tk=8.6.14=h6ba3021_0
- tornado=6.4.1=py312h80987f9_0
- tzdata=2024b=h04d1e81_0
- unicodedata2=15.1.0=py312h80987f9_0
- wheel=0.44.0=py312hca03da5_0
- xz=5.4.6=h80987f9_1
- zlib=1.2.13=h18a0788_1
- zstd=1.5.6=hfb09047_0
prefix: /opt/miniconda3/envs/qtm350--no-builds flag excludes build numbers from package specifications, making environment files more portable across different platforms and operating systemspy39h12345) encodes important metadata:
py39, py310linux_64, osx_arm64gcc9 (GNU/Linux), clang (macOS)nomkl (Intel), cuda (NVIDIA GPUs)environment.yml fileenvironment.yml file with them (or by uploading it to your repository!)conda env create --file environment.yml
Channels:
- defaults
Platform: osx-arm64
Collecting package metadata (repodata.json): done
Solving environment: done
Downloading and Extracting Packages:
Preparing transaction: done
Verifying transaction: done
Executing transaction: done
#
# To activate this environment, use
#
# $ conda activate qtm350
#
# To deactivate an active environment, use
#
# $ conda deactivate
(base) qtm350 with the same packages and versions as the original environmentrequirements.txt filepip instead of conda, you can generate a requirements.txt file with the following command:Bottleneck @ file:///private/var/folders/nz/j7p8yfhx1mv_0grj5xl4650h0000gp/T/abs_55txi4fy1u/croot/bottleneck_1731058642212/work
contourpy @ file:///Users/builder/cbouss/perseverance-python-buildout/croot/contourpy_1701814001737/work
cycler @ file:///tmp/build/80754af9/cycler_1637851556182/work
fonttools @ file:///private/var/folders/nz/j6p8yfhx1mv_0grj5xl4650h0000gp/T/abs_60c8ux4mkl/croot/fonttools_1713551354374/work
kiwisolver @ file:///Users/builder/cbouss/perseverance-python-buildout/croot/kiwisolver_1699239145780/work
matplotlib==3.9.2
numexpr @ file:///private/var/folders/nz/j6p8yfhx1mv_0grj5xl4650h0000gp/T/abs_b3kvvt6tc6/croot/numexpr_1730215947700/work
numpy @ file:///private/var/folders/k1/30mswbxs7r1g6zwn8y4fyt500000gp/T/abs_a51i_mbs7m/croot/numpy_and_numpy_base_1708638620867/work/dist/numpy-1.26.4-cp312-cp312-macosx_11_0_arm64.whl#sha256=37afb6b734a197702d848df93bd67c10b52f6467d56e518950d84b6b1c949d27
packaging @ file:///private/var/folders/k1/30mswbxs7r1g6zwn8y4fyt500000gp/T/abs_81ri4yfpjw/croot/packaging_1720101866878/work
pandas @ file:///private/var/folders/k1/30mswbxs7r1g6zwn8y4fyt500000gp/T/abs_b53hgou29t/croot/pandas_1718308972393/work/dist/pandas-2.2.2-cp312-cp312-macosx_11_0_arm64.whl#sha256=1956b71d1baac8b370fd9deac6100aadefda112447dca816a81ecbf3ea4eb3e6
pillow @ file:///private/var/folders/k1/30mswbxs7r1g6zwn8y4fyt500000gp/T/abs_92egn12how/croot/pillow_1731594702114/work
pyparsing @ file:///private/var/folders/nz/j6p8yfhx1mv_0grj5xl4650h0000gp/T/abs_65qfw6vkxg/croot/pyparsing_1731445528142/work
python-dateutil @ file:///private/var/folders/k1/30mswbxs7r1g6zwn8y4fyt500000gp/T/abs_66ud1l42_h/croot/python-dateutil_1716495741162/work
pytz @ file:///private/var/folders/k1/30mswbxs7r1g6zwn8y4fyt500000gp/T/abs_a4b76c83ik/croot/pytz_1713974318928/work
setuptools==75.1.0
six @ file:///tmp/build/80754af9/six_1644875935023/work
tornado @ file:///private/var/folders/k1/30mswbxs7r1g6zwn8y4fyt500000gp/T/abs_a4w03z48br/croot/tornado_1718740114858/work
tzdata @ file:///croot/python-tzdata_1690578112552/work
unicodedata2 @ file:///private/var/folders/k1/30mswbxs7r1g6zwn8y4fyt500000gp/T/abs_a3epjto7gs/croot/unicodedata2_1713212955584/work
wheel==0.44.0requirements.txt more portablepip freeze often includes local file paths that won’t work on other machinesrequirements.txt, we need to remove these local pathsgrep to filter out lines containing file://pip freeze: Lists all installed packagesgrep -v 'file://': Excludes lines containing file://> clean-requirements.txt: Saves the result to a new filerequirements.txt fileconda, and it is also widely used in the Python communityconda, and it does not manage environments as well (it only installs packages in the current environment)pipenv to manage your dependenciespipenv 🐍pip and virtualenv into a single tool# Install pipenv
pip install pipenv
# Create project directory and navigate to it
mkdir qtm350
cd qtm350
# Install packages (creates Pipfile automatically)
pipenv install numpy pandas matplotlib
# Activate the virtual environment
pipenv shell
# Run commands without activating
pipenv run python script.py
# Install development dependencies
pipenv install pytest --devPipfile: Human-readable file with direct dependencies (TOML format)
Pipfile.lock: Auto-generated with exact versions and hashes (JSON format)
Example Pipfile:
Pipfile and Pipfile.lock)pipenv install, and you’re done! 🎉build command, and they will produce a container when started with run. More about the distinction heredocker info
docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
478afc919002: Download complete
Digest: sha256:305243c734571da2d100c8c8b3c3167a098cab6049c9a5b066b6021a60fcb966
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.Dockerfile to build an image, which is a plain-text recipe that will build from scratch everything you need to recreate a projectDockerfileDockerfile is a text file that contains all the commands a user could call on the command line to assemble an imagedocker build, we can create an automated build that executes several command-line instructions in successiondocker and a file called Dockerfile inside itFROM <image_name>:<tag> is the base image, RUN is used to run bash commands while building the image, and CMD is used to specify which commands to run when the container starts-t is for “tag”, which names the image qtm350-example, and . is the current directory):conda, pip, or pipenv to manage your dependencies in Python