diff --git a/environment.yml b/environment.yml index 88f37a7..5e8bd48 100644 --- a/environment.yml +++ b/environment.yml @@ -1,7 +1,8 @@ name: python_for_systems_programming channels: - - defaults + - conda-forge dependencies: + - click - paramiko - matplotlib - jinja2 @@ -10,6 +11,10 @@ dependencies: - fabric - numpy - jupyterlab -pip: - - schedule -prefix: /home/gjb/miniconda3/envs/python_for_systems_programming + - uvicorn + - ca-certificates + - certifi + - openssl + - fastapi + - fire +prefix: /home/gjb/mambaforge/envs/python_for_systems_programming diff --git a/python_for_systems_programming.pptx b/python_for_systems_programming.pptx index 1c8cb47..df93b72 100644 Binary files a/python_for_systems_programming.pptx and b/python_for_systems_programming.pptx differ diff --git a/python_for_systems_programming_linux64_conda_specs.txt b/python_for_systems_programming_linux64_conda_specs.txt index 713937c..017ba52 100644 --- a/python_for_systems_programming_linux64_conda_specs.txt +++ b/python_for_systems_programming_linux64_conda_specs.txt @@ -2,142 +2,299 @@ # $ conda create --name --file # platform: linux-64 @EXPLICIT -https://repo.anaconda.com/pkgs/main/linux-64/_libgcc_mutex-0.1-main.conda -https://repo.anaconda.com/pkgs/main/linux-64/blas-1.0-mkl.conda -https://repo.anaconda.com/pkgs/main/linux-64/ca-certificates-2021.7.5-h06a4308_1.conda -https://repo.anaconda.com/pkgs/main/linux-64/intel-openmp-2021.3.0-h06a4308_3350.conda -https://repo.anaconda.com/pkgs/main/linux-64/ld_impl_linux-64-2.35.1-h7274673_9.conda -https://repo.anaconda.com/pkgs/main/linux-64/libstdcxx-ng-9.3.0-hd4cf53a_17.conda -https://repo.anaconda.com/pkgs/main/noarch/tzdata-2021a-h5d7bf9c_0.conda -https://repo.anaconda.com/pkgs/main/linux-64/libgomp-9.3.0-h5101ec6_17.conda -https://repo.anaconda.com/pkgs/main/linux-64/mkl-2021.3.0-h06a4308_520.conda -https://repo.anaconda.com/pkgs/main/linux-64/_openmp_mutex-4.5-1_gnu.tar.bz2 -https://repo.anaconda.com/pkgs/main/linux-64/libgcc-ng-9.3.0-h5101ec6_17.conda -https://repo.anaconda.com/pkgs/main/linux-64/brotli-1.0.9-he6710b0_2.conda -https://repo.anaconda.com/pkgs/main/linux-64/expat-2.4.1-h2531618_2.conda -https://repo.anaconda.com/pkgs/main/linux-64/icu-58.2-he6710b0_3.conda -https://repo.anaconda.com/pkgs/main/linux-64/jpeg-9b-h024ee3a_2.conda -https://repo.anaconda.com/pkgs/main/linux-64/libffi-3.3-he6710b0_2.conda -https://repo.anaconda.com/pkgs/main/linux-64/libsodium-1.0.18-h7b6447c_0.conda -https://repo.anaconda.com/pkgs/main/linux-64/libuuid-1.0.3-h1bed415_2.conda -https://repo.anaconda.com/pkgs/main/linux-64/libwebp-base-1.2.0-h27cfd23_0.conda -https://repo.anaconda.com/pkgs/main/linux-64/libxcb-1.14-h7b6447c_0.conda -https://repo.anaconda.com/pkgs/main/linux-64/lz4-c-1.9.3-h295c915_1.conda -https://repo.anaconda.com/pkgs/main/linux-64/ncurses-6.2-he6710b0_1.conda -https://repo.anaconda.com/pkgs/main/linux-64/openssl-1.1.1l-h7f8727e_0.conda +https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 +https://repo.anaconda.com/pkgs/main/linux-64/blas-1.0-openblas.conda +https://conda.anaconda.org/conda-forge/linux-64/ca-certificates-2024.2.2-hbcca054_0.conda +https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2 +https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2 +https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2 +https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_1.conda +https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.40-h41732ed_0.conda +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-13.2.0-h7e041cc_5.conda +https://conda.anaconda.org/conda-forge/linux-64/pandoc-3.1.13-ha770c72_0.conda +https://conda.anaconda.org/conda-forge/linux-64/python_abi-3.11-4_cp311.conda +https://conda.anaconda.org/conda-forge/noarch/tzdata-2024a-h0c530f3_0.conda +https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-0.tar.bz2 +https://conda.anaconda.org/conda-forge/linux-64/libgomp-13.2.0-h807b86a_5.conda +https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2 +https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-13.2.0-h807b86a_5.conda +https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.8-h166bdaf_0.tar.bz2 +https://conda.anaconda.org/conda-forge/linux-64/attr-2.5.1-h166bdaf_1.tar.bz2 +https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hd590300_5.conda +https://conda.anaconda.org/conda-forge/linux-64/gettext-tools-0.22.5-h59595ed_2.conda +https://conda.anaconda.org/conda-forge/linux-64/giflib-5.2.2-hd590300_0.conda +https://conda.anaconda.org/conda-forge/linux-64/gmp-6.3.0-h59595ed_1.conda +https://conda.anaconda.org/conda-forge/linux-64/graphite2-1.3.13-h59595ed_1003.conda +https://conda.anaconda.org/conda-forge/linux-64/gstreamer-orc-0.4.38-hd590300_0.conda +https://conda.anaconda.org/conda-forge/linux-64/icu-70.1-h27087fc_0.tar.bz2 +https://conda.anaconda.org/conda-forge/linux-64/jpeg-9e-h0b41bf4_3.conda +https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.1-h166bdaf_0.tar.bz2 +https://conda.anaconda.org/conda-forge/linux-64/lame-3.100-h166bdaf_1003.tar.bz2 +https://conda.anaconda.org/conda-forge/linux-64/lerc-4.0.0-h27087fc_0.tar.bz2 +https://conda.anaconda.org/conda-forge/linux-64/libasprintf-0.22.5-h661eb56_2.conda +https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.1.0-hd590300_1.conda +https://conda.anaconda.org/conda-forge/linux-64/libdb-6.2.32-h9c3ff4c_0.tar.bz2 +https://repo.anaconda.com/pkgs/main/linux-64/libdeflate-1.17-h5eee18b_0.conda +https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.6.2-h59595ed_0.conda +https://repo.anaconda.com/pkgs/main/linux-64/libffi-3.4.2-h6a678d5_6.conda +https://conda.anaconda.org/conda-forge/linux-64/libgettextpo-0.22.5-h59595ed_2.conda +https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-13.2.0-ha4646dd_5.conda +https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.17-hd590300_2.conda +https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hd590300_0.conda +https://conda.anaconda.org/conda-forge/linux-64/libogg-1.3.4-h7f98852_1.tar.bz2 +https://conda.anaconda.org/conda-forge/linux-64/libopus-1.3.1-h7f98852_1.tar.bz2 +https://conda.anaconda.org/conda-forge/linux-64/libsodium-1.0.18-h36c2ea0_1.tar.bz2 +https://conda.anaconda.org/conda-forge/linux-64/libtool-2.4.7-h27087fc_0.conda +https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.38.1-h0b41bf4_0.conda +https://repo.anaconda.com/pkgs/main/linux-64/libwebp-base-1.2.4-h5eee18b_1.conda +https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.2.13-hd590300_5.conda +https://repo.anaconda.com/pkgs/main/linux-64/lz4-c-1.9.4-h6a678d5_0.conda +https://conda.anaconda.org/conda-forge/linux-64/mpg123-1.32.6-h59595ed_0.conda +https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.4.20240210-h59595ed_0.conda +https://conda.anaconda.org/conda-forge/linux-64/nspr-4.35-h27087fc_0.conda +https://conda.anaconda.org/conda-forge/linux-64/openssl-3.1.5-hd590300_0.conda https://repo.anaconda.com/pkgs/main/linux-64/pcre-8.45-h295c915_0.conda -https://repo.anaconda.com/pkgs/main/linux-64/xz-5.2.5-h7b6447c_0.conda -https://repo.anaconda.com/pkgs/main/linux-64/zlib-1.2.11-h7b6447c_3.conda -https://repo.anaconda.com/pkgs/main/linux-64/glib-2.69.1-h5202010_0.conda -https://repo.anaconda.com/pkgs/main/linux-64/libpng-1.6.37-hbc83047_0.conda -https://repo.anaconda.com/pkgs/main/linux-64/libxml2-2.9.12-h03d6c58_0.conda -https://repo.anaconda.com/pkgs/main/linux-64/readline-8.1-h27cfd23_0.conda -https://repo.anaconda.com/pkgs/main/linux-64/tk-8.6.10-hbc83047_0.conda -https://repo.anaconda.com/pkgs/main/linux-64/zeromq-4.3.4-h2531618_0.conda -https://repo.anaconda.com/pkgs/main/linux-64/zstd-1.4.9-haebb681_0.conda -https://repo.anaconda.com/pkgs/main/linux-64/dbus-1.13.18-hb2f20db_0.conda -https://repo.anaconda.com/pkgs/main/linux-64/freetype-2.10.4-h5ab3b9f_0.conda -https://repo.anaconda.com/pkgs/main/linux-64/gstreamer-1.14.0-h28cd5cc_2.conda -https://repo.anaconda.com/pkgs/main/linux-64/libtiff-4.2.0-h85742a9_0.conda -https://repo.anaconda.com/pkgs/main/linux-64/sqlite-3.36.0-hc218d9a_0.conda -https://repo.anaconda.com/pkgs/main/linux-64/fontconfig-2.13.1-h6c09931_0.conda -https://repo.anaconda.com/pkgs/main/linux-64/gst-plugins-base-1.14.0-h8213a91_2.conda -https://repo.anaconda.com/pkgs/main/linux-64/lcms2-2.12-h3be6417_0.conda -https://repo.anaconda.com/pkgs/main/linux-64/openjpeg-2.4.0-h3ad879b_0.conda -https://repo.anaconda.com/pkgs/main/linux-64/python-3.9.6-h12debd9_1.conda -https://repo.anaconda.com/pkgs/main/noarch/async_generator-1.10-pyhd3eb1b0_0.tar.bz2 -https://repo.anaconda.com/pkgs/main/noarch/attrs-21.2.0-pyhd3eb1b0_0.conda +https://conda.anaconda.org/conda-forge/linux-64/pixman-0.43.2-h59595ed_0.conda +https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-h36c2ea0_1001.tar.bz2 +https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.38-h0b41bf4_0.conda +https://conda.anaconda.org/conda-forge/linux-64/xorg-kbproto-1.0.7-h7f98852_1002.tar.bz2 +https://conda.anaconda.org/conda-forge/linux-64/xorg-libice-1.1.1-hd590300_0.conda +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.11-hd590300_0.conda +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.3-h7f98852_0.tar.bz2 +https://conda.anaconda.org/conda-forge/linux-64/xorg-renderproto-0.11.1-h7f98852_1002.tar.bz2 +https://conda.anaconda.org/conda-forge/linux-64/xorg-xextproto-7.3.0-h0b41bf4_1003.conda +https://conda.anaconda.org/conda-forge/linux-64/xorg-xproto-7.0.31-h7f98852_1007.tar.bz2 +https://repo.anaconda.com/pkgs/main/linux-64/xz-5.2.10-h5eee18b_1.conda +https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h7f98852_2.tar.bz2 +https://conda.anaconda.org/conda-forge/linux-64/expat-2.6.2-h59595ed_0.conda +https://conda.anaconda.org/conda-forge/linux-64/jack-1.9.22-h11f4161_0.conda +https://conda.anaconda.org/conda-forge/linux-64/libasprintf-devel-0.22.5-h661eb56_2.conda +https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.1.0-hd590300_1.conda +https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.1.0-hd590300_1.conda +https://conda.anaconda.org/conda-forge/linux-64/libcap-2.67-he9d0100_0.conda +https://repo.anaconda.com/pkgs/main/linux-64/libedit-3.1.20221030-h5eee18b_0.conda +https://conda.anaconda.org/conda-forge/linux-64/libevent-2.1.10-h28343ad_4.tar.bz2 +https://conda.anaconda.org/conda-forge/linux-64/libgettextpo-devel-0.22.5-h59595ed_2.conda +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-13.2.0-h69a702a_5.conda +https://conda.anaconda.org/conda-forge/linux-64/libllvm14-14.0.6-hcd5def8_4.conda +https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.43-h2797004_0.conda +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.45.2-h2797004_0.conda +https://conda.anaconda.org/conda-forge/linux-64/libvorbis-1.3.7-h9c3ff4c_0.tar.bz2 +https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.13-h7f98852_1004.tar.bz2 +https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.10.3-hca2bb57_4.conda +https://conda.anaconda.org/conda-forge/linux-64/mysql-common-8.0.33-hf1915f5_6.conda +https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.43-hcad00b1_0.conda +https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8228510_1.conda +https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h4845f30_101.conda +https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.4-h7391055_0.conda +https://conda.anaconda.org/conda-forge/linux-64/zeromq-4.3.5-h59595ed_1.conda +https://conda.anaconda.org/conda-forge/linux-64/zlib-1.2.13-hd590300_5.conda +https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.1.0-hd590300_1.conda +https://conda.anaconda.org/conda-forge/linux-64/fftw-3.3.10-nompi_hc118613_108.conda +https://conda.anaconda.org/conda-forge/linux-64/freetype-2.12.1-h267a509_2.conda +https://conda.anaconda.org/conda-forge/linux-64/gettext-0.22.5-h59595ed_2.conda +https://conda.anaconda.org/conda-forge/linux-64/krb5-1.20.1-h81ceb04_0.conda +https://conda.anaconda.org/conda-forge/linux-64/libglib-2.80.0-hf2295e7_5.conda +https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.27-pthreads_h413a1c8_0.conda +https://conda.anaconda.org/conda-forge/linux-64/libudev1-253-h0b41bf4_1.conda +https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.5.0-h79f4944_1.conda +https://conda.anaconda.org/conda-forge/linux-64/libxslt-1.1.37-h873f0b0_0.tar.bz2 +https://conda.anaconda.org/conda-forge/linux-64/nss-3.98-h1d7d5a4_0.conda +https://conda.anaconda.org/conda-forge/linux-64/python-3.11.6-hab00c5b_0_cpython.conda +https://conda.anaconda.org/conda-forge/linux-64/sqlite-3.45.2-h2c6b66d_0.conda +https://conda.anaconda.org/conda-forge/linux-64/xcb-util-0.4.0-h516909a_0.tar.bz2 +https://conda.anaconda.org/conda-forge/linux-64/xcb-util-keysyms-0.4.0-h516909a_0.tar.bz2 +https://conda.anaconda.org/conda-forge/linux-64/xcb-util-renderutil-0.3.9-h166bdaf_0.tar.bz2 +https://conda.anaconda.org/conda-forge/linux-64/xcb-util-wm-0.4.1-h516909a_0.tar.bz2 +https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.4-h0b41bf4_0.conda +https://repo.anaconda.com/pkgs/main/linux-64/zstd-1.5.5-hc292b87_0.conda +https://conda.anaconda.org/conda-forge/noarch/attrs-23.2.0-pyh71513ae_0.conda https://repo.anaconda.com/pkgs/main/noarch/backcall-0.2.0-pyhd3eb1b0_0.tar.bz2 -https://repo.anaconda.com/pkgs/main/linux-64/certifi-2021.5.30-py39h06a4308_0.conda -https://repo.anaconda.com/pkgs/main/noarch/charset-normalizer-2.0.4-pyhd3eb1b0_0.conda -https://repo.anaconda.com/pkgs/main/linux-64/debugpy-1.4.1-py39h295c915_0.conda -https://repo.anaconda.com/pkgs/main/noarch/decorator-5.0.9-pyhd3eb1b0_0.conda +https://conda.anaconda.org/conda-forge/linux-64/bcrypt-4.1.2-py311h46250e7_0.conda +https://conda.anaconda.org/conda-forge/linux-64/brotli-1.1.0-hd590300_1.conda +https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.1.0-py311hb755f60_1.conda +https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2 +https://conda.anaconda.org/conda-forge/noarch/certifi-2024.2.2-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.3.2-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/click-8.1.7-unix_pyh707e725_0.conda +https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/linux-64/debugpy-1.8.1-py311hb755f60_0.conda +https://repo.anaconda.com/pkgs/main/noarch/decorator-5.1.1-pyhd3eb1b0_0.conda https://repo.anaconda.com/pkgs/main/noarch/defusedxml-0.7.1-pyhd3eb1b0_0.conda -https://repo.anaconda.com/pkgs/main/linux-64/entrypoints-0.3-py39h06a4308_0.conda -https://repo.anaconda.com/pkgs/main/noarch/idna-3.2-pyhd3eb1b0_0.conda -https://repo.anaconda.com/pkgs/main/linux-64/invoke-1.6.0-py39h06a4308_0.conda +https://repo.anaconda.com/pkgs/main/linux-64/entrypoints-0.4-py311h06a4308_0.conda +https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.2.0-pyhd8ed1ab_2.conda +https://conda.anaconda.org/conda-forge/noarch/executing-2.0.1-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.14.2-h14ed4e7_0.conda +https://conda.anaconda.org/conda-forge/linux-64/glib-tools-2.80.0-hde27a5a_5.conda +https://conda.anaconda.org/conda-forge/noarch/hpack-4.0.0-pyh9f0ad1d_0.tar.bz2 +https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.0.1-pyhd8ed1ab_0.tar.bz2 +https://conda.anaconda.org/conda-forge/noarch/idna-3.6-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/invoke-2.2.0-pyhd8ed1ab_0.conda https://repo.anaconda.com/pkgs/main/noarch/ipython_genutils-0.2.0-pyhd3eb1b0_1.conda -https://repo.anaconda.com/pkgs/main/noarch/json5-0.9.6-pyhd3eb1b0_0.conda -https://repo.anaconda.com/pkgs/main/linux-64/kiwisolver-1.3.1-py39h2531618_0.conda -https://repo.anaconda.com/pkgs/main/linux-64/markupsafe-2.0.1-py39h27cfd23_0.conda -https://repo.anaconda.com/pkgs/main/linux-64/mistune-0.8.4-py39h27cfd23_1000.conda +https://conda.anaconda.org/conda-forge/noarch/json5-0.9.25-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/linux-64/jsonpointer-2.4-py311h38be061_3.conda +https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.4.5-py311h9547e67_1.conda +https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-h36d4200_3.conda +https://conda.anaconda.org/conda-forge/linux-64/libflac-1.4.3-h59595ed_0.conda +https://conda.anaconda.org/conda-forge/linux-64/libgpg-error-1.48-h71f35ed_0.conda +https://conda.anaconda.org/conda-forge/linux-64/libllvm15-15.0.7-hadd5161_1.conda +https://conda.anaconda.org/conda-forge/linux-64/libpq-15.3-hbcd7760_1.conda +https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.5.0-h6adf6a1_2.conda +https://repo.anaconda.com/pkgs/main/linux-64/lxml-4.9.2-py311h5eee18b_0.conda +https://conda.anaconda.org/conda-forge/linux-64/markupsafe-2.1.5-py311h459d7ec_0.conda +https://conda.anaconda.org/conda-forge/noarch/mistune-3.0.2-pyhd8ed1ab_0.conda https://repo.anaconda.com/pkgs/main/noarch/munkres-1.1.4-py_0.conda -https://repo.anaconda.com/pkgs/main/noarch/nest-asyncio-1.5.1-pyhd3eb1b0_0.conda -https://repo.anaconda.com/pkgs/main/noarch/olefile-0.46-pyhd3eb1b0_0.conda -https://repo.anaconda.com/pkgs/main/linux-64/pandocfilters-1.4.3-py39h06a4308_1.conda -https://repo.anaconda.com/pkgs/main/noarch/parso-0.8.2-pyhd3eb1b0_0.conda +https://conda.anaconda.org/conda-forge/linux-64/mysql-libs-8.0.33-hca2cd23_6.conda +https://conda.anaconda.org/conda-forge/noarch/nest-asyncio-1.6.0-pyhd8ed1ab_0.conda +https://repo.anaconda.com/pkgs/main/linux-64/numpy-base-1.23.5-py311hc9e7d78_0.conda +https://conda.anaconda.org/conda-forge/noarch/packaging-24.0-pyhd8ed1ab_0.conda +https://repo.anaconda.com/pkgs/main/noarch/pandocfilters-1.5.0-pyhd3eb1b0_0.conda +https://conda.anaconda.org/conda-forge/noarch/parso-0.8.4-pyhd8ed1ab_0.conda https://repo.anaconda.com/pkgs/main/noarch/pickleshare-0.7.5-pyhd3eb1b0_1003.conda -https://repo.anaconda.com/pkgs/main/noarch/prometheus_client-0.11.0-pyhd3eb1b0_0.conda -https://repo.anaconda.com/pkgs/main/linux-64/psutil-5.8.0-py39h27cfd23_1.conda +https://conda.anaconda.org/conda-forge/noarch/pkgutil-resolve-name-1.3.10-pyhd8ed1ab_1.conda +https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.2.0-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/ply-3.11-pyhd8ed1ab_2.conda +https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.20.0-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/linux-64/psutil-5.9.8-py311h459d7ec_0.conda https://repo.anaconda.com/pkgs/main/noarch/ptyprocess-0.7.0-pyhd3eb1b0_2.conda -https://repo.anaconda.com/pkgs/main/noarch/pycparser-2.20-py_2.conda -https://repo.anaconda.com/pkgs/main/noarch/pyparsing-2.4.7-pyhd3eb1b0_0.tar.bz2 -https://repo.anaconda.com/pkgs/main/linux-64/pyrsistent-0.18.0-py39h7f8727e_0.conda -https://repo.anaconda.com/pkgs/main/linux-64/pysocks-1.7.1-py39h06a4308_0.conda -https://repo.anaconda.com/pkgs/main/noarch/pytz-2021.1-pyhd3eb1b0_0.conda -https://repo.anaconda.com/pkgs/main/linux-64/pyzmq-22.2.1-py39h295c915_1.conda -https://repo.anaconda.com/pkgs/main/linux-64/qt-5.9.7-h5867ecd_1.conda -https://repo.anaconda.com/pkgs/main/noarch/send2trash-1.5.0-pyhd3eb1b0_1.conda -https://repo.anaconda.com/pkgs/main/linux-64/sh-1.14.2-py39h06a4308_0.conda -https://repo.anaconda.com/pkgs/main/linux-64/sip-4.19.13-py39h2531618_0.conda -https://repo.anaconda.com/pkgs/main/noarch/six-1.16.0-pyhd3eb1b0_0.conda -https://repo.anaconda.com/pkgs/main/linux-64/sniffio-1.2.0-py39h06a4308_1.conda -https://repo.anaconda.com/pkgs/main/noarch/testpath-0.5.0-pyhd3eb1b0_0.conda -https://repo.anaconda.com/pkgs/main/linux-64/tornado-6.1-py39h27cfd23_0.conda -https://repo.anaconda.com/pkgs/main/noarch/wcwidth-0.2.5-pyhd3eb1b0_0.conda -https://repo.anaconda.com/pkgs/main/linux-64/webencodings-0.5.1-py39h06a4308_1.conda -https://repo.anaconda.com/pkgs/main/noarch/wheel-0.37.0-pyhd3eb1b0_1.conda -https://repo.anaconda.com/pkgs/main/noarch/zipp-3.5.0-pyhd3eb1b0_0.conda -https://repo.anaconda.com/pkgs/main/linux-64/anyio-2.2.0-py39h06a4308_1.conda -https://repo.anaconda.com/pkgs/main/noarch/babel-2.9.1-pyhd3eb1b0_0.conda -https://repo.anaconda.com/pkgs/main/linux-64/cffi-1.14.6-py39h400218f_0.conda -https://repo.anaconda.com/pkgs/main/linux-64/cycler-0.10.0-py39h06a4308_0.conda -https://repo.anaconda.com/pkgs/main/noarch/fonttools-4.25.0-pyhd3eb1b0_0.conda -https://repo.anaconda.com/pkgs/main/linux-64/importlib-metadata-3.10.0-py39h06a4308_0.conda -https://repo.anaconda.com/pkgs/main/linux-64/jedi-0.18.0-py39h06a4308_1.conda -https://repo.anaconda.com/pkgs/main/linux-64/mkl-service-2.4.0-py39h7f8727e_0.conda -https://repo.anaconda.com/pkgs/main/noarch/packaging-21.0-pyhd3eb1b0_0.conda -https://repo.anaconda.com/pkgs/main/noarch/pexpect-4.8.0-pyhd3eb1b0_3.conda -https://repo.anaconda.com/pkgs/main/linux-64/pillow-8.3.1-py39h2c7a002_0.conda -https://repo.anaconda.com/pkgs/main/noarch/prompt-toolkit-3.0.17-pyhca03da5_0.conda -https://repo.anaconda.com/pkgs/main/linux-64/pyqt-5.9.2-py39h2531618_6.conda -https://repo.anaconda.com/pkgs/main/noarch/python-dateutil-2.8.2-pyhd3eb1b0_0.conda -https://repo.anaconda.com/pkgs/main/linux-64/setuptools-52.0.0-py39h06a4308_0.conda -https://repo.anaconda.com/pkgs/main/linux-64/terminado-0.9.4-py39h06a4308_0.conda -https://repo.anaconda.com/pkgs/main/noarch/traitlets-5.0.5-pyhd3eb1b0_0.tar.bz2 -https://repo.anaconda.com/pkgs/main/linux-64/argon2-cffi-20.1.0-py39h27cfd23_1.conda -https://repo.anaconda.com/pkgs/main/noarch/bleach-4.0.0-pyhd3eb1b0_0.conda -https://repo.anaconda.com/pkgs/main/linux-64/brotlipy-0.7.0-py39h27cfd23_1003.conda -https://repo.anaconda.com/pkgs/main/linux-64/cryptography-3.4.7-py39hd23ed53_0.conda -https://repo.anaconda.com/pkgs/main/noarch/importlib_metadata-3.10.0-hd3eb1b0_0.conda -https://repo.anaconda.com/pkgs/main/noarch/jinja2-3.0.1-pyhd3eb1b0_0.conda -https://repo.anaconda.com/pkgs/main/linux-64/jupyter_core-4.7.1-py39h06a4308_0.conda -https://repo.anaconda.com/pkgs/main/noarch/matplotlib-inline-0.1.2-pyhd3eb1b0_2.conda -https://repo.anaconda.com/pkgs/main/linux-64/numpy-base-1.20.3-py39h74d4b33_0.conda -https://repo.anaconda.com/pkgs/main/linux-64/pip-21.2.4-py37h06a4308_0.conda -https://repo.anaconda.com/pkgs/main/noarch/pygments-2.10.0-pyhd3eb1b0_0.conda -https://repo.anaconda.com/pkgs/main/linux-64/pynacl-1.4.0-py39he8ac12f_1.conda -https://repo.anaconda.com/pkgs/main/linux-64/bcrypt-3.2.0-py39he8ac12f_0.conda -https://repo.anaconda.com/pkgs/main/linux-64/ipython-7.26.0-py39hb070fc8_0.conda -https://repo.anaconda.com/pkgs/main/noarch/jsonschema-3.2.0-pyhd3eb1b0_2.conda -https://repo.anaconda.com/pkgs/main/noarch/jupyter_client-7.0.1-pyhd3eb1b0_0.conda -https://repo.anaconda.com/pkgs/main/noarch/jupyterlab_pygments-0.1.2-py_0.conda -https://repo.anaconda.com/pkgs/main/noarch/pyopenssl-20.0.1-pyhd3eb1b0_1.conda -https://repo.anaconda.com/pkgs/main/linux-64/ipykernel-6.2.0-py39h06a4308_1.conda -https://repo.anaconda.com/pkgs/main/noarch/nbformat-5.1.3-pyhd3eb1b0_0.conda -https://repo.anaconda.com/pkgs/main/noarch/paramiko-2.7.2-py_0.conda -https://repo.anaconda.com/pkgs/main/noarch/urllib3-1.26.6-pyhd3eb1b0_1.conda -https://repo.anaconda.com/pkgs/main/linux-64/fabric-2.6.0-py39h06a4308_0.conda -https://repo.anaconda.com/pkgs/main/noarch/nbclient-0.5.3-pyhd3eb1b0_0.conda -https://repo.anaconda.com/pkgs/main/noarch/requests-2.26.0-pyhd3eb1b0_0.conda -https://repo.anaconda.com/pkgs/main/linux-64/nbconvert-6.1.0-py39h06a4308_0.conda -https://repo.anaconda.com/pkgs/main/linux-64/jupyter_server-1.4.1-py39h06a4308_0.conda -https://repo.anaconda.com/pkgs/main/linux-64/notebook-6.4.3-py39h06a4308_0.conda -https://repo.anaconda.com/pkgs/main/noarch/jupyterlab_server-2.7.2-pyhd3eb1b0_0.conda -https://repo.anaconda.com/pkgs/main/noarch/nbclassic-0.2.6-pyhd3eb1b0_0.conda -https://repo.anaconda.com/pkgs/main/noarch/jupyterlab-3.1.7-pyhd3eb1b0_0.conda -https://repo.anaconda.com/pkgs/main/linux-64/matplotlib-3.4.2-py39h06a4308_0.conda -https://repo.anaconda.com/pkgs/main/linux-64/matplotlib-base-3.4.2-py39hab158f2_0.conda -https://repo.anaconda.com/pkgs/main/linux-64/mkl_fft-1.3.0-py39h42c9631_2.conda -https://repo.anaconda.com/pkgs/main/linux-64/mkl_random-1.2.2-py39h51133e4_0.conda -https://repo.anaconda.com/pkgs/main/linux-64/numpy-1.20.3-py39hf144106_0.conda +https://repo.anaconda.com/pkgs/main/noarch/pure_eval-0.2.2-pyhd3eb1b0_0.conda +https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/pygments-2.17.2-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.1.2-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/linux-64/pyrsistent-0.20.0-py311h459d7ec_0.conda +https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha2e5f31_6.tar.bz2 +https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.19.1-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/python-json-logger-2.0.7-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/pytz-2024.1-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.1-py311h459d7ec_1.conda +https://conda.anaconda.org/conda-forge/linux-64/pyzmq-26.0.0-py311h34ded2d_0.conda +https://conda.anaconda.org/conda-forge/noarch/rfc3986-validator-0.1.1-pyh9f0ad1d_0.tar.bz2 +https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.18.0-py311h46250e7_0.conda +https://conda.anaconda.org/conda-forge/noarch/send2trash-1.8.3-pyh0d859eb_0.conda +https://conda.anaconda.org/conda-forge/noarch/setuptools-69.5.1-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/sh-2.0.6-pyh707e725_0.conda +https://repo.anaconda.com/pkgs/main/noarch/six-1.16.0-pyhd3eb1b0_1.conda +https://conda.anaconda.org/conda-forge/noarch/sniffio-1.3.1-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.5-pyhd8ed1ab_1.conda +https://conda.anaconda.org/conda-forge/noarch/termcolor-2.4.0-pyhd8ed1ab_0.conda +https://repo.anaconda.com/pkgs/main/noarch/toml-0.10.2-pyhd3eb1b0_0.conda +https://repo.anaconda.com/pkgs/main/linux-64/tomli-2.0.1-py311h06a4308_0.conda +https://conda.anaconda.org/conda-forge/linux-64/tornado-6.4-py311h459d7ec_0.conda +https://conda.anaconda.org/conda-forge/noarch/traitlets-5.14.2-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/types-python-dateutil-2.9.0.20240316-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.11.0-pyha770c72_0.conda +https://conda.anaconda.org/conda-forge/noarch/typing_utils-0.1.0-pyhd8ed1ab_0.tar.bz2 +https://conda.anaconda.org/conda-forge/noarch/uri-template-1.3.0-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.2.13-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/webcolors-1.13-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/webencodings-0.5.1-pyhd8ed1ab_2.conda +https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.7.0-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/wheel-0.43.0-pyhd8ed1ab_1.conda +https://conda.anaconda.org/conda-forge/linux-64/wrapt-1.16.0-py311h459d7ec_0.conda +https://conda.anaconda.org/conda-forge/linux-64/xcb-util-image-0.4.0-h166bdaf_0.tar.bz2 +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.4-h0b41bf4_2.conda +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.10-h7f98852_1003.tar.bz2 +https://conda.anaconda.org/conda-forge/noarch/zipp-3.17.0-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/anyio-4.3.0-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/asttokens-2.4.1-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/async-lru-2.0.4-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/babel-2.14.0-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.12.3-pyha770c72_0.conda +https://conda.anaconda.org/conda-forge/noarch/bleach-6.1.0-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2 +https://conda.anaconda.org/conda-forge/linux-64/cairo-1.16.0-ha61ee94_1014.tar.bz2 +https://conda.anaconda.org/conda-forge/linux-64/cffi-1.16.0-py311hb3a22ac_0.conda +https://conda.anaconda.org/conda-forge/noarch/comm-0.2.2-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/deprecated-1.2.14-pyh1a96a4e_0.conda +https://conda.anaconda.org/conda-forge/noarch/fire-0.6.0-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.51.0-py311h459d7ec_0.conda +https://conda.anaconda.org/conda-forge/linux-64/glib-2.80.0-hf2295e7_5.conda +https://conda.anaconda.org/conda-forge/noarch/h11-0.14.0-pyhd8ed1ab_0.tar.bz2 +https://conda.anaconda.org/conda-forge/noarch/h2-4.1.0-pyhd8ed1ab_0.tar.bz2 +https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-7.1.0-pyha770c72_0.conda +https://conda.anaconda.org/conda-forge/noarch/importlib_resources-6.4.0-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/jedi-0.19.1-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.3-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/linux-64/jupyter_core-5.7.2-py311h38be061_0.conda +https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_1.conda +https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.15-hfd0df8a_0.conda +https://conda.anaconda.org/conda-forge/linux-64/libclang13-15.0.7-default_h5d6823c_5.conda +https://conda.anaconda.org/conda-forge/linux-64/libgcrypt-1.10.3-hd590300_0.conda +https://conda.anaconda.org/conda-forge/linux-64/libsndfile-1.2.2-hc60ed4a_1.conda +https://repo.anaconda.com/pkgs/main/linux-64/libwebp-1.2.4-h11a3e52_1.conda +https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.1.7-pyhd8ed1ab_0.conda +https://repo.anaconda.com/pkgs/main/linux-64/numpy-1.23.5-py311h5585df3_0.conda +https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.0-hfec8fc6_2.conda +https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/pexpect-4.9.0-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/pip-24.0-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.42-pyha770c72_0.conda +https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/referencing-0.34.0-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/rfc3339-validator-0.1.4-pyhd8ed1ab_0.tar.bz2 +https://conda.anaconda.org/conda-forge/linux-64/sip-6.7.12-py311hb755f60_0.conda +https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.1-pyh0d859eb_0.conda +https://repo.anaconda.com/pkgs/main/linux-64/tinycss2-1.2.1-py311h06a4308_0.conda +https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.11.0-hd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/urllib3-2.2.1-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.6.0-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/linux-64/argon2-cffi-bindings-21.2.0-py311h459d7ec_4.conda +https://conda.anaconda.org/conda-forge/noarch/arrow-1.3.0-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/linux-64/brotlipy-0.7.0-py311h459d7ec_1006.conda +https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.2.1-py311h9547e67_0.conda +https://conda.anaconda.org/conda-forge/linux-64/cryptography-42.0.2-py311hcb13ee4_0.conda +https://repo.anaconda.com/pkgs/main/linux-64/dbus-1.13.18-hb2f20db_0.conda +https://conda.anaconda.org/conda-forge/noarch/fqdn-1.5.1-pyhd8ed1ab_0.tar.bz2 +https://conda.anaconda.org/conda-forge/linux-64/gstreamer-1.22.0-h25f0c4b_2.conda +https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-6.0.0-h8e241bc_0.conda +https://conda.anaconda.org/conda-forge/noarch/httpcore-1.0.5-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/importlib_metadata-7.1.0-hd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2023.12.1-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/jupyter_server_terminals-0.5.3-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/linux-64/libclang-15.0.7-default_h127d8a8_5.conda +https://conda.anaconda.org/conda-forge/linux-64/libsystemd0-253-h8c4010b_1.conda +https://conda.anaconda.org/conda-forge/linux-64/pillow-9.4.0-py311h50def17_1.conda +https://conda.anaconda.org/conda-forge/linux-64/pydantic-core-2.18.1-py311h46250e7_0.conda +https://conda.anaconda.org/conda-forge/linux-64/pynacl-1.5.0-py311h459d7ec_3.conda +https://conda.anaconda.org/conda-forge/linux-64/pyqt5-sip-12.12.2-py311hb755f60_5.conda +https://conda.anaconda.org/conda-forge/noarch/requests-2.31.0-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.2-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/starlette-0.37.2-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/linux-64/uvicorn-0.29.0-py311h38be061_0.conda +https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-23.1.0-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/linux-64/gst-plugins-base-1.22.0-h4243ec0_2.conda +https://conda.anaconda.org/conda-forge/noarch/httpx-0.27.0-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/ipython-8.22.2-pyh707e725_0.conda +https://conda.anaconda.org/conda-forge/noarch/isoduration-20.11.0-pyhd8ed1ab_0.tar.bz2 +https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.21.1-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.6.1-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.8.4-py311h54ef318_0.conda +https://conda.anaconda.org/conda-forge/noarch/paramiko-3.4.0-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/linux-64/pulseaudio-client-16.1-h5195f5e_3.conda +https://conda.anaconda.org/conda-forge/noarch/pydantic-2.7.0-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/pyopenssl-24.0.0-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/fabric-3.2.2-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/fastapi-0.110.1-pyhd8ed1ab_1.conda +https://conda.anaconda.org/conda-forge/noarch/ipykernel-6.29.3-pyhd33586a_0.conda +https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.21.1-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/nbformat-5.10.4-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/linux-64/pulseaudio-daemon-16.1-ha8d29e2_3.conda +https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.10.0-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/nbclient-0.10.0-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/linux-64/pulseaudio-16.1-hcb278e6_3.conda +https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.16.3-pyhd8ed1ab_1.conda +https://conda.anaconda.org/conda-forge/linux-64/qt-main-5.15.8-h5d23da1_6.conda +https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.14.0-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/nbconvert-pandoc-7.16.3-hd8ed1ab_1.conda +https://conda.anaconda.org/conda-forge/linux-64/pyqt-5.15.9-py311hf0fb5b6_5.conda +https://conda.anaconda.org/conda-forge/linux-64/qt-webengine-5.15.8-h77d6d84_0.tar.bz2 +https://conda.anaconda.org/conda-forge/linux-64/qtwebkit-5.212-h3e5094c_8.conda +https://conda.anaconda.org/conda-forge/noarch/jupyter-lsp-2.2.5-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.26.0-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.8.4-py311h38be061_0.conda +https://conda.anaconda.org/conda-forge/noarch/nbconvert-7.16.3-hd8ed1ab_1.conda +https://conda.anaconda.org/conda-forge/noarch/notebook-shim-0.2.4-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.1.6-pyhd8ed1ab_0.conda +https://conda.anaconda.org/conda-forge/noarch/nbclassic-1.0.0-pyhb4ecaf3_1.conda +https://conda.anaconda.org/conda-forge/noarch/notebook-7.1.2-pyhd8ed1ab_0.conda diff --git a/source-code/README.md b/source-code/README.md index 85a5439..0fbb406 100644 --- a/source-code/README.md +++ b/source-code/README.md @@ -44,3 +44,4 @@ to create it. There is some material not covered in the presentation as well. 1. `subprocess`: illustrates executing a shell command from a Python script using the `subprocess` module. 1. `xml-generator`: code to generate a random XML documents. +1. `fastapi`: simple illustrations of using FastAPI for webservices. diff --git a/source-code/code-evaluation/fac.py b/source-code/code-evaluation/fac.py index 8c66954..e440327 100644 --- a/source-code/code-evaluation/fac.py +++ b/source-code/code-evaluation/fac.py @@ -1,5 +1,2 @@ def fac(n): - if n < 2: - return 1 - else: - return n*fac(n-1) + return 1 if n < 2 else n*fac(n-1) diff --git a/source-code/code-evaluation/fib.py b/source-code/code-evaluation/fib.py index da4b04b..0486ae2 100644 --- a/source-code/code-evaluation/fib.py +++ b/source-code/code-evaluation/fib.py @@ -1,5 +1,2 @@ def fib(n): - if n == 0 or n == 1: - return 1 - else: - return fib(n-1) + fib(n-2) + return 1 if n in [0, 1] else fib(n-1) + fib(n-2) diff --git a/source-code/command-line-arguments/ArgParse/README.md b/source-code/command-line-arguments/ArgParse/README.md index c9de23c..974ee5d 100644 --- a/source-code/command-line-arguments/ArgParse/README.md +++ b/source-code/command-line-arguments/ArgParse/README.md @@ -23,3 +23,4 @@ $ ./generate_gaussian.py -h ./options_in_file.py --foo something @file_options.txt ``` 1. `file_options.txt`: file containing options for `options_in_file.py`. +1. `Rerun`: experiment with file options. diff --git a/source-code/command-line-arguments/ArgParse/Rerun/README.md b/source-code/command-line-arguments/ArgParse/Rerun/README.md new file mode 100644 index 0000000..4f6318b --- /dev/null +++ b/source-code/command-line-arguments/ArgParse/Rerun/README.md @@ -0,0 +1,33 @@ +# Rerunnable + +Toy application to explore the possibilities created by +using argparse options stored in a file. + + +## What is it? +1. rerunnable.py`: script to explore the possibilities. + + +## How to use? + +```bash +$ ./rerunnable.py --verbose --number 5 --type bye gjb +$ ./rerunnable.py @rerunnable_cla.txt +``` + +This will rerun the application with all the settings specified for the +previous run. + +To override options: +```bash +$ ./rerunnable.py @rerunnable_cla.txt --number 3 +``` + + +## Conclusions + +This approach works well for command line options, e.g., `--number 5`. + +It is not flexibile for flags, e.g., `--verbose` since they can not be "unset". + +It is not flexible either for positional arguments since they can not be modified. diff --git a/source-code/command-line-arguments/ArgParse/Rerun/rerunnable.py b/source-code/command-line-arguments/ArgParse/Rerun/rerunnable.py new file mode 100755 index 0000000..7cb1c7c --- /dev/null +++ b/source-code/command-line-arguments/ArgParse/Rerun/rerunnable.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python + +import argparse + + +def dump_options(options, pos_args=None, exclude=None): + options_dict = vars(options) + with open('rerunnable_cla.txt', 'w') as file: + for key, value in options_dict.items(): + if ((exclude is None or key not in exclude) and + (pos_args is None or key not in pos_args)): + if isinstance(value, bool): + if value: + print(f'--{key}', file=file) + else: + print(f'--{key}\n{value}', file=file) + if pos_args is not None: + for key in pos_args: + print(options_dict[key], file=file) + + +if __name__ == '__main__': + arg_parser = argparse.ArgumentParser( + fromfile_prefix_chars='@', + description='application that saves its command line options and can be rerun' + ) + arg_parser.add_argument('--number', type=int, default=1, + help='number of messages to write') + arg_parser.add_argument('--type', choices=('hello', 'bye'), default='hello', + help='message type') + arg_parser.add_argument('--verbose', action='store_true', + help='verbose output') + arg_parser.add_argument('name', help='person to message') + options = arg_parser.parse_args() + dump_options(options, pos_args=('name', )) + if options.verbose: + print(f'printing {options.number} messages') + for _ in range(options.number): + print(f'{options.type} {options.name}') diff --git a/source-code/command-line-arguments/ArgParse/options_in_file.py b/source-code/command-line-arguments/ArgParse/options_in_file.py index 552a149..0733c4a 100755 --- a/source-code/command-line-arguments/ArgParse/options_in_file.py +++ b/source-code/command-line-arguments/ArgParse/options_in_file.py @@ -3,14 +3,14 @@ import argparse -def amin(): +def main(): arg_parser = argparse.ArgumentParser(fromfile_prefix_chars='@') arg_parser.add_argument('--foo', help='foo option') - arg_parser.add_argument('--bar', help='bar optoin') + arg_parser.add_argument('--bar', help='bar option') arg_parser.add_argument('--flag', action='store_true', help='flag option') options = arg_parser.parse_args() print(options) if __name__ == '__main__': - amin() + main() diff --git a/source-code/command-line-arguments/ArgParse/partial_parse.py b/source-code/command-line-arguments/ArgParse/partial_parse.py index f9af425..723e74e 100755 --- a/source-code/command-line-arguments/ArgParse/partial_parse.py +++ b/source-code/command-line-arguments/ArgParse/partial_parse.py @@ -19,5 +19,5 @@ options.resoure_specs)) print('resources: ' + ', '.join(specs)) if options.account: - print('account: ' + options.account) + print(f'account: {options.account}') print('unparsed: ' + ', '.join(unparsed)) diff --git a/source-code/command-line-arguments/ArgParse/two_stage_parse.py b/source-code/command-line-arguments/ArgParse/two_stage_parse.py index 3ff1533..5600692 100755 --- a/source-code/command-line-arguments/ArgParse/two_stage_parse.py +++ b/source-code/command-line-arguments/ArgParse/two_stage_parse.py @@ -7,7 +7,7 @@ def parse_job_script(file_name): - args = list() + args = [] with open(file_name) as file: for line in file: if line.lstrip().startswith('#PBS '): diff --git a/source-code/command-line-arguments/Fire/README.md b/source-code/command-line-arguments/Fire/README.md index b87fbac..9579383 100644 --- a/source-code/command-line-arguments/Fire/README.md +++ b/source-code/command-line-arguments/Fire/README.md @@ -5,8 +5,10 @@ applications with a command line interface. ## What is it? -1. `calculator.py`/`calculations.py`: Calculator application that +1. `calculator.py`/`calculations.py`: calculator application that implements addition, substraction, multiplication and division. -1. `sayer.py`: Illustration of grouped commands. +1. `sayer.py`: illustration of grouped commands. 1. `cl_logger.py`/`log_management.py`/`log_operations.py`: logging from the command line example. +1. `job.py`: simple class definition to explore interacting with + objects from the CLI. diff --git a/source-code/command-line-arguments/Fire/calculations.py b/source-code/command-line-arguments/Fire/calculations.py index ac5546c..52bc2d1 100644 --- a/source-code/command-line-arguments/Fire/calculations.py +++ b/source-code/command-line-arguments/Fire/calculations.py @@ -1,14 +1,17 @@ -def add(x, y): +def add(x: float, y: float) -> float: return x + y -def sub(x, y): +def sub(x: float, y: float) -> float: return x - y -def mult(x, y): +def mult(x: float, y: float) -> float: return x*y -def div(x, y): +def div(x: float, y: float) -> float: return x/y -def mod(x, y): +def idiv(x: int, y: int) -> int: + return x//y + +def mod(x: int, y: int) -> int: return x % y diff --git a/source-code/command-line-arguments/Fire/calculator.py b/source-code/command-line-arguments/Fire/calculator.py index b9b03a4..e5be3b0 100755 --- a/source-code/command-line-arguments/Fire/calculator.py +++ b/source-code/command-line-arguments/Fire/calculator.py @@ -1,6 +1,7 @@ #!/usr/bin/env python -import fire + import calculations +import fire if __name__ == '__main__': diff --git a/source-code/command-line-arguments/Fire/job.py b/source-code/command-line-arguments/Fire/job.py new file mode 100755 index 0000000..979883d --- /dev/null +++ b/source-code/command-line-arguments/Fire/job.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python +import fire + + +class Job: + + _nodes: int + _ntasks: int + + def __init__(self, nodes=1, ntasks=1): + self.nodes = nodes + self.ntasks = ntasks + + @property + def nodes(self): + return self._nodes + + @nodes.setter + def nodes(self, nodes): + self._nodes = nodes + return self + + + @property + def ntasks(self): + return self._ntasks + + @ntasks.setter + def ntasks(self, ntasks): + self._ntasks = ntasks + return self + + def print(self): + return f'nodes={self.nodes} ntasks={self.ntasks}' + +if __name__ == '__main__': + fire.Fire(Job) diff --git a/source-code/command-line-arguments/Fire/sayer.py b/source-code/command-line-arguments/Fire/sayer.py index b583433..9b90d5b 100755 --- a/source-code/command-line-arguments/Fire/sayer.py +++ b/source-code/command-line-arguments/Fire/sayer.py @@ -12,13 +12,12 @@ def __init__(self, name): self.name = name def to(self, name=None): - if name is None: - if self.name is None: - return 'No one to say hello to' - else: - return f'Hello to {self.name}' - else: + if name is not None: return f'Hello {name}' + if self.name is None: + return 'No one to say hello to' + else: + return f'Hello to {self.name}' def everyone(self): return 'hello to everyone' @@ -34,15 +33,12 @@ def __init__(self, name): def to(self, name=None): if name is None: - if self.name is None: - return 'No one to say bye to' - else: - return f'Bye to {self.name}' + return 'No one to say bye to' if self.name is None else f'Bye to {self.name}' else: return f'Bye {name}' def no_one(self): - return f'Bye to no one' + return 'Bye to no one' class Sayer: diff --git a/source-code/config-parser/config_reader.py b/source-code/config-parser/config_reader.py index 1ac31be..af46e60 100755 --- a/source-code/config-parser/config_reader.py +++ b/source-code/config-parser/config_reader.py @@ -5,10 +5,7 @@ def main(): - if len(sys.argv) > 1: - cfg_file = sys.argv[1] - else: - cfg_file = 'defaults.conf' + cfg_file = sys.argv[1] if len(sys.argv) > 1 else 'defaults.conf' cfg_parser = SafeConfigParser() cfg_parser.read(cfg_file) print('Sections:') diff --git a/source-code/data-formats/Vcd/vcd_parser.py b/source-code/data-formats/Vcd/vcd_parser.py index 4f874fc..8dba30e 100755 --- a/source-code/data-formats/Vcd/vcd_parser.py +++ b/source-code/data-formats/Vcd/vcd_parser.py @@ -15,7 +15,7 @@ def parse_config_line(meta_data, line): meta_data[symbol] = demangle_name(name) def parse_config(vcd_file): - meta_data = dict() + meta_data = {} for line in vcd_file: line = line.strip() if line == '$end': @@ -37,16 +37,15 @@ def update_buffer(buffer, line, meta_data): buffer[key] = value def init_data(meta_data): - data = dict() - data['time'] = list() + data = {'time': []} for var in meta_data: - data[meta_data[var]] = list() + data[meta_data[var]] = [] return data def parse_data(vcd_file, meta_data): data = init_data(meta_data) time_stamp = None - buffer = dict() + buffer = {} for line in vcd_file: line = line.strip() if line.startswith('#'): @@ -68,9 +67,7 @@ def write_vcd_data_structure(out_file, data, sep=' '): columns = list(data.keys()) out_file.write(sep.join(columns) + '\n') for time_step in range(len(data['time'])): - data_line = list() - for var in columns: - data_line.append(data[var][time_step]) + data_line = [data[var][time_step] for var in columns] out_file.write(sep.join(str(data_item) for data_item in data_line)) out_file.write('\n') diff --git a/source-code/data-formats/agt_parser.py b/source-code/data-formats/agt_parser.py index 7c396dd..d3336fa 100755 --- a/source-code/data-formats/agt_parser.py +++ b/source-code/data-formats/agt_parser.py @@ -106,7 +106,7 @@ def _parse_data(self, agt_file): if not match: msg = "line {0:d}: invalid number of measurements '{1}'" raise AgtDataError(msg.format(self._current_line, nr_lines_str)) - nr_lines = int(match.group(1)) + nr_lines = int(match[1]) self._current_line += 1 # ignore header line agt_file.readline() diff --git a/source-code/data-formats/data_generator.py b/source-code/data-formats/data_generator.py index 5928860..06c0009 100755 --- a/source-code/data-formats/data_generator.py +++ b/source-code/data-formats/data_generator.py @@ -47,11 +47,10 @@ def __iter__(self): return self def __next__(self): - if self._current < self.n: - self._current += 1 - return self._distr(*self._params) - else: + if self._current >= self.n: raise StopIteration() + self._current += 1 + return self._distr(*self._params) class DistributionCreator(object): @@ -108,9 +107,9 @@ def __init__(self, file_name, table_name, col_defs): self._row = self._table.row def _create_table(self, table_name, col_defs): - description = {} - for col_def in col_defs: - description[col_def['name']] = self._typemap[col_def['type']] + description = { + col_def['name']: self._typemap[col_def['type']] for col_def in col_defs + } return self._file.create_table('/', table_name, description) def set_headers(self, headers): diff --git a/source-code/data-formats/read_csv.py b/source-code/data-formats/read_csv.py index b14ab73..3989bf8 100755 --- a/source-code/data-formats/read_csv.py +++ b/source-code/data-formats/read_csv.py @@ -21,7 +21,7 @@ def main(): print('{name} --- {weight}'.format(name=row['name'], weight=row['weight'])) sum += float(row['weight']) - print('sum = {}'.format(sum)) + print(f'sum = {sum}') if __name__ == '__main__': main() diff --git a/source-code/data-formats/read_variable_length_array.py b/source-code/data-formats/read_variable_length_array.py index a84ea9f..c3ba07a 100755 --- a/source-code/data-formats/read_variable_length_array.py +++ b/source-code/data-formats/read_variable_length_array.py @@ -13,10 +13,8 @@ def read_array(data_file, length): arg_parser.add_argument('file', help='binary file to read') options = arg_parser.parse_args() with open(options.file, 'rb') as data_file: - buffer = data_file.read(4); - while buffer: + while buffer := data_file.read(4): length = unpack('I', buffer)[0] values = read_array(data_file, length) value_str = ' '.join(f'{x:.2f}' for x in values) print(f'{length:d}: {value_str:s}') - buffer = data_file.read(4) diff --git a/source-code/data-formats/read_xml.py b/source-code/data-formats/read_xml.py index b3ba195..c02a6c6 100755 --- a/source-code/data-formats/read_xml.py +++ b/source-code/data-formats/read_xml.py @@ -62,8 +62,7 @@ def startElement(self, name, attrs): def characters(self, contents): if self.in_item: - contents = contents.strip() - if contents: + if contents := contents.strip(): data = float(contents.strip()) logging.info(f"found '{data}'") self._stack[-1].add_data(data) diff --git a/source-code/fastapi/README.md b/source-code/fastapi/README.md new file mode 100644 index 0000000..6d69b8d --- /dev/null +++ b/source-code/fastapi/README.md @@ -0,0 +1,26 @@ +# FastAPI + +FastAPI is a nice framework to build web applications and handle http requests. + +## What is it? + +* `main.py`: very simple hello world application. +* `calculator.py`: implementation of an API that allows to + * push numbers on a stack (push/) + * perform a computation (compute/add or compute/mult) +* `calculations.sh`: shell script to illustrate use of the calculator API. + +## How to use it? + +### Hello world application +```bash +$ uvicorn main:app --reload +``` + +### Calculator +```bash +$ uvicorn calculatorapp --reload +$ curl --silent http://127.0.0.1:8000/push/5 +$ curl --silent http://127.0.0.1:8000/push/7 +$ curl --silent http://127.0.0.1:8000/compute/add +``` diff --git a/source-code/fastapi/calculations.sh b/source-code/fastapi/calculations.sh new file mode 100755 index 0000000..dc32f0a --- /dev/null +++ b/source-code/fastapi/calculations.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash + +# start the server with +# uvivorn calculator::app --reload +# + +source ~/.mamba_init.sh +mamba activate python_for_systems_programming + +HOST=127.0.0.1:8000 + +echo "push 5" +curl --silent "http://$HOST/push/5" +echo "" + +echo "push 7" +curl --silent "http://$HOST/push/7" +echo "" + +echo "perform addition" +curl --silent "http://$HOST/compute/add" | json_pp +echo "" diff --git a/source-code/fastapi/calculator.py b/source-code/fastapi/calculator.py new file mode 100644 index 0000000..3f0b03c --- /dev/null +++ b/source-code/fastapi/calculator.py @@ -0,0 +1,19 @@ +from fastapi import FastAPI +from typing import Union + +app = FastAPI() +stack = [] + +@app.get('/push/{value}') +def push(value: float, q: Union[str, None] = None): + stack.append(value) + +@app.get('/compute/{operator}') +def compute(operator: str, q: Union[str, None] = None): + right_operand = stack.pop() + left_operand = stack.pop() + if operator == 'add': + result = left_operand + right_operand + elif operator == 'mult': + result = left_operand*right_operand + return {'result': result} diff --git a/source-code/fastapi/main.py b/source-code/fastapi/main.py new file mode 100644 index 0000000..a83fa35 --- /dev/null +++ b/source-code/fastapi/main.py @@ -0,0 +1,20 @@ +from typing import Union +from fastapi import FastAPI + +app = FastAPI() + + +@app.get("/") +def read_root(): + return {"Hello": "World"} + + +@app.get("/items/{item_id}") +def read_item(item_id: int, q: Union[str, None] = None): + return {"item_id": item_id, "q": q} + + +@app.get("/users/{user_id}&{category}") +def read_item(user_id: int, category: str, + q: Union[str, None] = None): + return {"user_id": user_id, "category": category, "q": q} diff --git a/source-code/file-system/list_files.py b/source-code/file-system/list_files.py index d6868f9..6551cf0 100755 --- a/source-code/file-system/list_files.py +++ b/source-code/file-system/list_files.py @@ -16,8 +16,7 @@ options = arg_parser.parse_args() for directory, _, files in os.walk(options.dir): if options.verbose: - print("### checking directory '{}'".format(directory), - file=sys.stderr) + print(f"### checking directory '{directory}'", file=sys.stderr) for file_name in files: _, ext = os.path.splitext(file_name) if ext == options.ext: diff --git a/source-code/jinja/reporting.py b/source-code/jinja/reporting.py index 89444b9..fb6663b 100755 --- a/source-code/jinja/reporting.py +++ b/source-code/jinja/reporting.py @@ -9,12 +9,11 @@ def generate_person(): - person = { - 'id': ''.join(random.choices(string.ascii_letters, k=5)), + return { + 'id': ''.join(random.choices(string.ascii_letters, k=5)), 'birthyear': random.randint(1950, 2015), 'nr_friends': random.randint(0, 50), } - return person def main(): arg_parser = ArgumentParser(description='generate random people') @@ -29,7 +28,7 @@ def main(): people = [generate_person() for _ in range(options.n)] environment = Environment(loader=PackageLoader('population', 'templates'), trim_blocks=True, lstrip_blocks=True) - template = environment.get_template('report.' + options.format) + template = environment.get_template(f'report.{options.format}') print(template.render(people=people)) if __name__ == '__main__': diff --git a/source-code/logging/log_it_all.py b/source-code/logging/log_it_all.py index 02ad53a..18575e1 100755 --- a/source-code/logging/log_it_all.py +++ b/source-code/logging/log_it_all.py @@ -30,17 +30,11 @@ def main(): help='number of times to do stuff') options = arg_parser.parse_args() format_str = '%(asctime)s:%(levelname)s:%(message)s' - if options.info: - level = logging.INFO - else: - level = logging.WARNING - if options.new_log: - filemode = 'w' - else: - filemode = 'a' + level = logging.INFO if options.info else logging.WARNING if options.log_file: log_file = Path(options.log_file) exists = log_file.exists() + filemode = 'w' if options.new_log else 'a' logging.basicConfig(level=level, filename=options.log_file, filemode=filemode, format=format_str) else: diff --git a/source-code/paramiko/ls.py b/source-code/paramiko/ls.py index 8e4c27b..4ee8ae0 100755 --- a/source-code/paramiko/ls.py +++ b/source-code/paramiko/ls.py @@ -24,7 +24,7 @@ def connect(host, user): ssh = connect(options.host, options.user) cmd = 'ls -l' if options.dir: - cmd += ' ' + options.dir + cmd += f' {options.dir}' _, stdout, stderr = ssh.exec_command(cmd) for line in stdout: print(line.rstrip()) diff --git a/source-code/paramiko/ssh_interaction.ipynb b/source-code/paramiko/ssh_interaction.ipynb index 6cf710d..ab71097 100644 --- a/source-code/paramiko/ssh_interaction.ipynb +++ b/source-code/paramiko/ssh_interaction.ipynb @@ -9,7 +9,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2018-11-14T10:36:38.868834Z", @@ -36,6 +36,13 @@ "**Important note:** some servers have a limit on the number of successful or unsuccessful logins for a time period. If that limit is exceeded, your IP address will be banned for some time. Hence be careful never to make a large number of connections over a short period of time!" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Important note:** the key to use for authentication by Paramiko should be the first one in your SSH agent. If necessary, delete other keys using `ssh-add -d ` for the other keys. If necessary, they can be added again later." + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -45,7 +52,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2018-11-14T10:36:39.400422Z", @@ -60,7 +67,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2018-11-14T10:36:39.436614Z", @@ -69,12 +76,12 @@ }, "outputs": [], "source": [ - "hostname = 'login1.hpc.kuleuven.be'" + "hostname = 'login.hpc.kuleuven.be'" ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2018-11-14T10:36:40.092803Z", @@ -83,7 +90,7 @@ }, "outputs": [], "source": [ - "client.connect(hostname, username='vsc30140')" + "client.connect(hostname, username='vsc30140', )" ] }, { @@ -95,7 +102,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2018-11-14T10:36:40.182797Z", @@ -116,27 +123,14 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2018-11-14T10:36:40.231362Z", "start_time": "2018-11-14T10:36:40.203599Z" } }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "-rw-r----- 1 vsc30140 vsc30140 222 Aug 30 14:00 hello.pbs\n", - "-rw-r----- 1 vsc30140 vsc30140 112 Jun 1 09:21 hello_world.pbs\n", - "-rw-r----- 1 vsc30140 vsc30140 162 Nov 8 16:15 job.pbs\n", - "-rw-r----- 1 vsc30140 vsc30140 197 Oct 24 09:46 oe_test.pbs\n", - "-rw-r----- 1 vsc30140 vsc30140 174 Mar 15 2017 plot.pbs\n", - "-rw-r----- 1 vsc30140 vsc30140 125 Nov 13 13:35 test.pbs\n" - ] - } - ], + "outputs": [], "source": [ "for line in stdout:\n", " print(line.strip())" @@ -158,7 +152,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2018-11-14T10:36:40.281831Z", @@ -172,47 +166,28 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2018-11-14T10:36:40.371737Z", "start_time": "2018-11-14T10:36:40.299343Z" } }, - "outputs": [ - { - "data": { - "text/plain": [ - "2" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "stdout.channel.recv_exit_status()" ] }, { "cell_type": "code", - "execution_count": 9, + "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2018-11-14T10:36:40.404423Z", "start_time": "2018-11-14T10:36:40.380884Z" } }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "ls: cannot access this_file_certainly_does_not_exists.txt: No such file or directory\n" - ] - } - ], + "outputs": [], "source": [ "print(''.join(stderr).rstrip())" ] @@ -233,7 +208,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2018-11-14T10:36:40.446074Z", @@ -254,7 +229,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2018-11-14T10:36:40.746892Z", @@ -278,7 +253,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2018-11-14T10:36:40.782534Z", @@ -286,15 +261,7 @@ }, "scrolled": true }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - " 174 645 6270\n" - ] - } - ], + "outputs": [], "source": [ "print(''.join(stdout).rstrip())" ] @@ -308,29 +275,21 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2018-11-14T10:36:40.992710Z", "start_time": "2018-11-14T10:36:40.805880Z" } }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - " 174 645 6270 julia_omp.f90\r\n" - ] - } - ], + "outputs": [], "source": [ "!wc julia_omp.f90" ] }, { "cell_type": "code", - "execution_count": 14, + "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2018-11-14T10:36:41.075964Z", @@ -351,7 +310,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2018-11-14T10:36:41.427788Z", @@ -372,7 +331,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2018-11-14T10:36:41.510158Z", @@ -393,7 +352,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2018-11-14T10:36:41.566153Z", @@ -408,7 +367,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2018-11-14T10:36:41.671042Z", @@ -429,23 +388,14 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2018-11-14T10:36:41.720460Z", "start_time": "2018-11-14T10:36:41.682944Z" } }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "-rw-r--r-- 1 vsc30140 vsc30140 6270 Nov 14 11:36 julia_omp.f90\n", - "\n" - ] - } - ], + "outputs": [], "source": [ "_, stdout, stderr = client.exec_command(f'ls -l {input_path}')\n", "print(''.join(stdout).rstrip())\n", @@ -461,7 +411,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2018-11-14T10:36:41.772076Z", @@ -482,22 +432,14 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2018-11-14T10:36:41.826462Z", "start_time": "2018-11-14T10:36:41.788142Z" } }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n" - ] - } - ], + "outputs": [], "source": [ "print(''.join(stderr).rstrip())" ] @@ -511,7 +453,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2018-11-14T10:36:41.910432Z", @@ -525,22 +467,14 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2018-11-14T10:36:42.115621Z", "start_time": "2018-11-14T10:36:41.919377Z" } }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - " 174 645 6270 julia_omp.f90\r\n" - ] - } - ], + "outputs": [], "source": [ "!cat julia_omp_wc.txt" ] @@ -554,7 +488,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2018-11-14T10:36:42.179519Z", @@ -575,7 +509,7 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2018-11-14T10:36:42.235726Z", @@ -596,7 +530,7 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2018-11-14T10:36:42.288331Z", @@ -612,7 +546,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, @@ -626,9 +560,9 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.6.6" + "version": "3.11.3" } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } diff --git a/source-code/processes/monitor.py b/source-code/processes/monitor.py index 403a75d..836e36c 100755 --- a/source-code/processes/monitor.py +++ b/source-code/processes/monitor.py @@ -47,10 +47,14 @@ def find_ancestor(pid=None, username=None): username = get_username() process = psutil.Process(pid) parents = process.parents() - for parent in reversed(parents): - if parent.username() == username: - return parent - return process + return next( + ( + parent + for parent in reversed(parents) + if parent.username() == username + ), + process, + ) def get_cmdline(process): @@ -63,11 +67,11 @@ def get_affinity(process): def get_read_open_files(process): - open_files = list() + open_files = [] try: for file in process.open_files(): try: - if 'r' == file.mode: + if file.mode == 'r': open_files.append(file.path) except: pass @@ -77,11 +81,11 @@ def get_read_open_files(process): def get_write_open_files(process): - open_files = list() + open_files = [] try: for file in process.open_files(): try: - if 'r' != file.mode: + if file.mode != 'r': open_files.append(f'{file.path}:{Path(file.path).stat().st_size}') except: pass @@ -91,8 +95,7 @@ def get_write_open_files(process): def define_actions(inactive=None): - metrics = dict() - metrics['time'] = Metric('time', lambda x: time.time()) + metrics = {'time': Metric('time', lambda x: time.time())} metrics['node'] = Metric('node', lambda x: platform.node()) metrics['pid'] = Metric('pid', lambda x: x.pid) metrics['ppid'] = Metric('ppid', lambda x: x.ppid()) @@ -121,11 +124,13 @@ def status_header(metrics): def process_status(process, metrics): '''Show properties of the specified process''' - status = list() + status = [] with process.oneshot(): - for metric in metrics.values(): - if metric.is_active: - status.append(metric.measure(process)) + status.extend( + metric.measure(process) + for metric in metrics.values() + if metric.is_active + ) return ','.join(status) @@ -150,20 +155,18 @@ def main(): if not options.affinity: inactive.append('affinity') if not options.files: - inactive.append('read_files') - inactive.append('write_files') + inactive.extend(('read_files', 'write_files')) metrics = define_actions(inactive) - if options.output_file: - file = open(options.output_file, 'w') - else: - file = sys.stdout + file = open(options.output_file, 'w') if options.output_file else sys.stdout try: with file: print(status_header(metrics), file=file) while True: process_info = [process_status(process, metrics)] - for child_process in process.children(recursive=True): - process_info.append(process_status(child_process, metrics)) + process_info.extend( + process_status(child_process, metrics) + for child_process in process.children(recursive=True) + ) print('\n'.join(process_info), file=file) time.sleep(options.delta) except KeyboardInterrupt: diff --git a/source-code/subprocess/async_handling.py b/source-code/subprocess/async_handling.py index 782904d..f30d91b 100755 --- a/source-code/subprocess/async_handling.py +++ b/source-code/subprocess/async_handling.py @@ -23,8 +23,7 @@ def execute(cmd, result): for stderr_line in iter(process.stderr.readline, ''): yield stderr_line.strip() stdout, stderr = process.communicate() - return_code = process.wait() - if return_code: + if return_code := process.wait(): raise subprocess.CalledProcessError(return_code, cmd) else: result.set(stdout) diff --git a/source-code/subprocess/wc_metrics.py b/source-code/subprocess/wc_metrics.py index b264c2f..4fbf202 100755 --- a/source-code/subprocess/wc_metrics.py +++ b/source-code/subprocess/wc_metrics.py @@ -1,7 +1,7 @@ #!/usr/bin/env python from argparse import ArgumentParser -from subprocess import check_output, CalledProcessError, STDOUT +import subprocess class WcInfo: @@ -58,11 +58,12 @@ def main(): args = arg_parser.parse_args() for f in args.files: try: - stats = check_output(['wc', f], stderr=STDOUT) - wc_info = WcInfo(stats.decode(encoding='utf-8')) + stats = subprocess.run(['wc', f], capture_output=True, + text=True, check=True) + wc_info = WcInfo(stats.stdout) print(wc_info) print(compute_stats(wc_info)) - except CalledProcessError as e: + except subprocess.CalledProcessError as e: print(e) if __name__ == '__main__': diff --git a/source-code/xml-generator/gen_xml.py b/source-code/xml-generator/gen_xml.py index 10ef38e..d37613d 100755 --- a/source-code/xml-generator/gen_xml.py +++ b/source-code/xml-generator/gen_xml.py @@ -54,10 +54,7 @@ def random(self): for _ in range(self._size): tag = self._tags.random() element = doc.createElement(tag) - if node_list: - parent = random.choice(node_list) - else: - parent = doc + parent = random.choice(node_list) if node_list else doc parent.appendChild(element) node_list.append(element) for element in node_list: