# Install Python packages inside 3D Slicer's bundled Python
Use this when a Slicer script, scripted module, or Python-interactor session needs
a package that is not part of Slicer's bundled Python. Slicer 5.x ships its own
Python 3.9 with its own site-packages — the system Python is irrelevant and must
never be mixed in.
## 1. Always use Slicer's own pip through `slicer.util.pip_install`
From the Python interactor (View / Python Interactor):
```python
import slicer
slicer.util.pip_install('requests') # one package
slicer.util.pip_install('ipywidgets pandas ipyevents ipycanvas') # space-separated = multiple
slicer.util.pip_install('--upgrade pillow --force-reinstall') # pip flags pass straight through
```
Do **not** run the system `pip`, and do **not** copy packages from the system
`site-packages` into Slicer's. Core developers state plainly that copying binary
packages from another Python into Slicer's site-packages does not work and can
prevent Slicer from starting. If you are outside the interactor, use Slicer's
Python executable directly:
- Windows: `PythonSlicer.exe -m pip install [package]` (from Slicer's `bin` directory)
- macOS: `/Applications/Slicer.app/Contents/bin/python-real -m pip install [package]`
A pip upgrade notice like "To update, run: python-real.exe -m pip install --upgrade pip"
is followed the same way.
## 2. Classify the failure from the error text FIRST
### `ModuleNotFoundError: No module named 'X'` after installing
Two distinct causes, check in order:
1. **The pip install actually failed.** `pip_install` raises
`subprocess.CalledProcessError: Command '[...PythonSlicer... -m pip install X]'
returned non-zero exit status 1` when pip fails, so look at the pip output
above it — the real cause is there.
2. **Wrong package name.** The classic: `pip_install('opencv')` fails with
`ERROR: Could not find a version that satisfies the requirement opencv
(from versions: none)`. The PyPI name is `opencv-python`:
`slicer.util.pip_install('opencv-python')`. (Alternatively install the
SlicerOpenCV extension, which provides OpenCV with Python bindings.)
### `Could not find a version that satisfies the requirement X (from versions: none)`
- If it happens for **every** package (test with `pip_install('requests')`),
pip cannot reach the index — no network, proxy, or firewall. Fix the network,
not the package.
- If only one package fails, the name is wrong or no wheel exists for Slicer's
Python (e.g. a package with no Python 3.9 wheel).
### Importing `torch` gets the CPU build or fails
`pip_install('torch')` installs the CPU-only wheel by default. For a CUDA build,
pass the PyTorch CUDA index through to pip (flags pass through, see above):
```python
slicer.util.pip_install('torch --index-url https://download.pytorch.org/whl/cu118')
```
Pick the `cuXXX` tag that matches your GPU driver — pytorch.org's Get Started
page lists the current tags. Note that torch is large; module developers
typically gate it behind an on-demand check in the module's logic
(`try: import torch / except ModuleNotFoundError: slicer.util.pip_install(...)`)
rather than at module load, so a failed download never bricks the module.
### `pip install numpy -U` fails from the interactor with access-denied errors
Slicer modules import numpy at startup, so Windows refuses to replace the file
while Slicer is running. Install it from the command line instead, with Slicer
**not running**:
```
PythonSlicer.exe -m pip install numpy -U
```
And think twice before doing it at all: Slicer builds pin numpy (the 5.4-era
builds ship numpy 1.26.4), and the numpy 2.0 release was announced on the Slicer
forum with an explicit warning not to upgrade numpy in Slicer because it breaks
builds. Only upgrade numpy if a required package genuinely demands it, and
verify Slicer still starts and imports its modules afterward.
## 3. Verify in the interactor, restart if needed
After a successful install, import the package immediately in the interactor to
confirm. Most packages work without a restart; pure-Python installs that pull
upgraded dependencies of already-imported packages may need one — the console
has a `restart()` command for exactly this. If the import fails after a
successful install, restart Slicer and try the import again before doing
anything else.