Python Packages
tiCrypt VMs do not have internet access, so pip install cannot reach the public PyPI index. Instead, your administrator maintains an offline Python package mirror on the NFS share with roughly 2,400 pre-downloaded packages covering data science, machine learning, NLP, genomics, visualization, and more.
This guide covers both Linux and Windows Server VMs. All commands run from a VM terminal. No internet and no special permissions are needed.
For a technical explanation of the mirror's architecture and design, see the companion article. For admin setup and maintenance, see the admin guide.
Run /drives/Software/pypi-mirror/pypi-mirror.sh readme from any terminal to print a self-contained reference guide covering all commands, tips, and usage examples.
Installing Packages
The mirror script and packages live on an NFS share that your administrator attaches to your VM. Inside the VM, tiCrypt presents it like any other drive:
- Linux: under
/drives/, using the NFS mount's name in title case. A mount namedsoftwareappears at/drives/Software. - Windows: as a drive letter, set by the NFS mount's slot.
The examples on this page assume the mirror sits in the pypi-mirror folder of a mount named software: /drives/Software/pypi-mirror/ on Linux and Z:\pypi-mirror\ on Windows. To find yours, run ls /drives on Linux or open This PC on Windows.
There are four ways to install packages:
Methods 1, 2, and 3 use the pypi-mirror.sh bash script and are available on Linux VMs only. On Windows Server VMs, skip to Method 4 to install packages directly with pip.
The mirror downloads prebuilt wheels for Linux only (manylinux2014_x86_64, CPython 3.9 to 3.12). On Windows, only pure-Python packages install from it: packages with compiled code, such as numpy or pandas, have no Windows wheel in the mirror and fail to install.
Method 1: Install the Full Curated Set
/drives/Software/pypi-mirror/pypi-mirror.sh install
With no arguments, install installs every package in the curated list plus anything in custom-packages.txt. Packages that are already installed are skipped automatically.
Method 2: Install Specific Packages
/drives/Software/pypi-mirror/pypi-mirror.sh install numpy pandas scikit-learn
Only the named packages (and their dependencies, resolved from the local mirror) are installed. Already-installed packages are skipped.
You can also pin specific versions. Each update adds the newest versions to the mirror without removing older ones, so the mirror can hold several versions of a package side by side, and pip resolves whichever of them you request. Quote any specifier that contains > or <, or the shell treats it as a redirection:
/drives/Software/pypi-mirror/pypi-mirror.sh install numpy==1.26.4 "pandas>=2.0"
Version pinning works with all install methods, including text files and direct pip install:
pip install numpy==1.26.4
pip install "pandas>=2.0,<2.2"
Method 3: Install from a Text File
/drives/Software/pypi-mirror/pypi-mirror.sh install requirements.txt
The script reads package names from any .txt file (one package per line). Blank lines and lines starting with # are ignored. You can mix text files and package names in the same command:
/drives/Software/pypi-mirror/pypi-mirror.sh install requirements.txt extra-package
This pairs well with pip freeze > requirements.txt. Freeze your working environment, then recreate it on another VM or after a venv rebuild by running install requirements.txt.
Method 4: Use pip install Directly
You can use pip install with the --no-index and --find-links flags to point pip at the mirror directory. This method works on both Linux and Windows VMs, but on Windows only for pure-Python packages (see the note above).
Linux:
pip install --no-index --find-links /drives/Software/pypi-mirror/pypi-packages numpy
Windows (Command Prompt):
pip install --no-index --find-links Z:\pypi-mirror\pypi-packages openpyxl
Replace Z: with the drive letter of the NFS share on your VM.
Configuring pip for Automatic Mirror Resolution
To avoid typing the flags every time, configure pip to always resolve from the local mirror.
Linux: create ~/.pip/pip.conf pointing at the mirror's path inside your VM:
mkdir -p ~/.pip
cat > ~/.pip/pip.conf <<'EOF'
[global]
no-index = true
find-links = file:///drives/Software/pypi-mirror/pypi-packages
EOF
Do not copy the pip.conf that sits next to the script. Your administrator generates it on the NFS server, so it contains the server's path to the mirror, which does not exist inside your VM.
Some Linux distributions look for pip configuration at ~/.config/pip/pip.conf instead of ~/.pip/pip.conf. If pip install still tries to reach the network after creating the file, copy it to the other location as well (or symlink one to the other).
Windows: create pip.ini in your %APPDATA%\pip\ directory:
mkdir %APPDATA%\pip
Then create the file %APPDATA%\pip\pip.ini with this content:
[global]
no-index = true
find-links = Z:\pypi-mirror\pypi-packages
Replace Z: with the drive letter of the NFS share on your VM.
On Windows, you can create the file from the command prompt:
echo [global] > %APPDATA%\pip\pip.ini
echo no-index = true >> %APPDATA%\pip\pip.ini
echo find-links = Z:\pypi-mirror\pypi-packages >> %APPDATA%\pip\pip.ini
After configuring pip (either platform), pip install <package> resolves from the local mirror automatically:
pip install numpy
Method 4 skips the automatic virtualenv detection that Methods 1, 2, and 3 provide. Activate the virtualenv you want first, since plain pip install installs into whatever environment (or system Python) happens to be active.
Where Packages Install
You should always install packages into a virtualenv rather than system-wide. This keeps your environment isolated and avoids conflicts with other users or the system Python.
Linux VMs (Methods 1-3)
When you use pypi-mirror.sh install, the script handles virtualenv detection automatically:
- It checks whether a virtualenv is already activated (the
$VIRTUAL_ENVenvironment variable is set). If so, it installs there. - If not, it looks for an existing virtualenv at
./venv,./.venv, or~/venvin that order, and activates the first one it finds. - If none exist, it creates a new virtualenv at
./venvin your current working directory and activates it.
Windows VMs (Method 4)
On Windows, create and activate a virtualenv manually before running pip install:
Command Prompt:
python -m venv %USERPROFILE%\venv
%USERPROFILE%\venv\Scripts\activate
PowerShell:
python -m venv $env:USERPROFILE\venv
& $env:USERPROFILE\venv\Scripts\Activate.ps1
Once activated, all pip install commands install into that venv.
Why Virtualenvs Matter
Packages install into a virtualenv you own (the script uses ./venv in your current directory or ~/venv), not a shared system location. This means:
- Per-user isolation. Each researcher has their own Python environment. Nothing you install affects anyone else's VM session or environment.
- Version independence. One researcher can run
numpy 1.26while another runsnumpy 2.0, in the same mirror, at the same time, with no conflict. - No conflicts. Installing or upgrading a package in your venv never touches another user's packages, even on a shared VM.
- No sudo required. You manage your own packages without needing administrator privileges on the VM.
- Multiple environments. You can create separate venvs for separate projects and activate whichever one you need before running
install. - Easy cleanup. To start fresh, delete the venv directory (for example,
rm -rf ./venv) and runinstallagain to recreate it.
If you want packages installed into a specific virtualenv rather than the one pypi-mirror.sh would auto-detect, activate it yourself first (source ./my-venv/bin/activate) before running the install command. The script always prefers an already-activated environment.
Tips
If you open a new terminal session, your virtualenv is not automatically active. Activate it first:
Linux:
source ~/venv/bin/activate
To make this automatic, add that line to your ~/.bashrc or ~/.bash_profile.
Windows (Command Prompt):
%USERPROFILE%\venv\Scripts\activate
Windows (PowerShell):
& $env:USERPROFILE\venv\Scripts\Activate.ps1
After installing the packages you need, freeze them to a file so you (or a collaborator) can recreate the same environment later:
pip freeze > requirements.txt
To recreate from the file:
pip install -r requirements.txt
Rather than installing everything into a single environment, create separate venvs for separate analyses. This prevents version conflicts between projects:
Linux:
python3 -m venv ~/projects/rna-seq/venv
source ~/projects/rna-seq/venv/bin/activate
/drives/Software/pypi-mirror/pypi-mirror.sh install scanpy anndata
Windows:
python -m venv %USERPROFILE%\projects\reports\venv
%USERPROFILE%\projects\reports\venv\Scripts\activate
pip install openpyxl
If a package seems missing after installation, confirm you are running the right Python:
Linux:
which python3
which pip
Both should point to paths inside your active venv (e.g., ~/venv/bin/python3), not /usr/bin/python3.
Windows:
where python
where pip
Both should point to your venv's Scripts\ directory (e.g., C:\Users\you\venv\Scripts\python.exe), not C:\Python312\python.exe.
The mirror may contain multiple versions of the same package. To upgrade one:
pip install --upgrade numpy
This only changes numpy (and its direct dependencies) inside your venv. Other users and other venvs are unaffected.
Virtualenvs can grow over time. To reclaim space without losing your package list:
Linux:
pip freeze > ~/my-packages.txt
rm -rf ~/venv
python3 -m venv ~/venv
source ~/venv/bin/activate
pip install -r ~/my-packages.txt
Windows:
pip freeze > %USERPROFILE%\my-packages.txt
rmdir /s /q %USERPROFILE%\venv
python -m venv %USERPROFILE%\venv
%USERPROFILE%\venv\Scripts\activate
pip install -r %USERPROFILE%\my-packages.txt
All pip install commands above work offline as long as pip.conf is in place or you pass --no-index --find-links /drives/Software/pypi-mirror/pypi-packages manually. The mirror handles resolution; no internet is needed.
Install vs. Update
These are two different commands for two different roles:
| Command | Who runs it | Where | What it does |
|---|---|---|---|
install | Researcher | Air-gapped VM | Installs packages from the mirror into your venv. Skips packages already installed. |
update | Administrator | NFS mount (internet) | Re-downloads all packages to the latest versions, refreshing the mirror on the NFS share. |
After your administrator runs update to refresh the mirror, you can pick up the new versions by upgrading individual packages:
pip install --upgrade numpy
Or rebuild your venv from scratch. On Linux, install with no arguments then installs the full curated set at the newest versions in the mirror. On Windows, reinstalling from the frozen list restores the exact versions it pins; delete the ==version part of each line in my-packages.txt first to get the newest versions:
Linux:
pip freeze > ~/my-packages.txt
rm -rf ~/venv
python3 -m venv ~/venv
source ~/venv/bin/activate
/drives/Software/pypi-mirror/pypi-mirror.sh install
Windows:
pip freeze > %USERPROFILE%\my-packages.txt
rmdir /s /q %USERPROFILE%\venv
python -m venv %USERPROFILE%\venv
%USERPROFILE%\venv\Scripts\activate
pip install -r %USERPROFILE%\my-packages.txt
Using the Mirror with Conda
If you prefer conda for environment management, you can still install packages from the offline mirror. Conda environments include their own pip, so both tools work together.
Installing Mirror Packages into a Conda Environment
conda create downloads Python and its dependencies from a conda channel, which an offline VM cannot reach. Activate a conda environment that is already in the VM image instead, or create a virtualenv if the image has none:
conda env list
conda activate <env-name>
Then install from the mirror using the --find-links flag with the path for your platform:
Linux:
pip install --no-index --find-links /drives/Software/pypi-mirror/pypi-packages numpy pandas scikit-learn
Windows:
pip install --no-index --find-links Z:\pypi-mirror\pypi-packages openpyxl
If pip.conf is configured (see Method 4 above), the last command simplifies to:
pip install numpy pandas scikit-learn
When combining conda and pip in the same environment, install conda packages first, then pip packages. Reversing the order can cause conda's dependency solver to overwrite files that pip installed, leading to broken packages. Once you start using pip in a conda environment, avoid running conda install again in that environment.
What the Mirror Does Not Cover
The mirror contains Python wheels from PyPI. It does not include conda packages (the .conda / .tar.bz2 format served by conda-forge, bioconda, or defaults channels). If you need a package that is only available as a conda package and not on PyPI, ask your administrator about setting up a separate conda channel mirror.
Practical recommendation: use conda to activate and manage the environments already in your VM image, and use pip with the offline mirror to install packages into those environments. This gives you the organizational benefits of conda with access to the full mirror catalog.
Searching and Listing
To check whether a package is in the mirror before trying to install it:
/drives/Software/pypi-mirror/pypi-mirror.sh search torch
This searches mirrored filenames for the term (case-insensitive) and prints every match.
To see everything available, with versions:
/drives/Software/pypi-mirror/pypi-mirror.sh list
Requesting New Packages
If search comes up empty, the package is not in the mirror yet. Contact your administrator and ask them to run:
./pypi-mirror.sh add <package>
on the NFS mount (which has internet access). The package downloads immediately and persists across future mirror updates. No VM restart or image rebuild is needed.
If you have write access to the NFS share, you can also add the package name directly to custom-packages.txt yourself and ask an admin to run update to pull it down.
Troubleshooting
"Mirror directory not found at .../pypi-packages. Run 'pypi-mirror.sh mirror' on an internet-connected machine first."
The NFS share does not have a completed mirror on it yet, or the script is not running from the NFS mount. Confirm the share is mounted and contains a pypi-packages/ directory; if not, ask your administrator to run mirror on the NFS mount.
"No matching distribution found for <package>" and search finds nothing.
The package is not in the mirror yet. Ask your administrator to add it (see Requesting New Packages).
"No matching distribution found" even though search finds the package.
The files search found do not fit your VM. The mirror holds prebuilt wheels for CPython 3.9 to 3.12 on Linux (manylinux2014_x86_64) and pure-Python wheels; check python3 --version (or python --version on Windows). Windows VMs and other Python versions cannot use the Linux wheels of packages with compiled code. If the mirror only has a source distribution (.tar.gz) for the package, pip builds it instead, which requires compiler and header packages (gcc, python3-dev or python3-devel, make) on the VM. Ask your admin whether these build tools are installed.
Installs from the mirror are slow.
Installing directly from an NFS-mounted pypi-packages/ directory can be slow depending on network storage performance. Consider copying pypi-packages/ to local disk on the VM and pointing find-links at the local copy. A full mirror is roughly 60 to 100 GB, so copy it only if your home drive has that much free space (check with df -h).
pip install still tries to reach the network after creating pip.conf.
Check both possible locations: ~/.pip/pip.conf and ~/.config/pip/pip.conf. Some distributions use one, some the other. Copy the file to both or symlink one to the other.
which python3 (Linux) or where python (Windows) points to the system Python instead of your venv.
Your virtualenv is not activated. On Linux, run source ~/venv/bin/activate. On Windows, run %USERPROFILE%\venv\Scripts\activate. Activate your venv before running pip commands.
Windows: pip install says "access denied" or writes to a system directory.
You are installing without an activated virtualenv, and the system Python directory requires admin privileges. Create and activate a venv first (see Windows VMs).
Windows: PowerShell blocks Activate.ps1 with an execution policy error.
PowerShell's default execution policy blocks scripts. Run Set-ExecutionPolicy -Scope CurrentUser RemoteSigned once, then try activating again. Alternatively, use Command Prompt where activate.bat runs without restriction.