Twitter

Python venv

A lot of application running on our VMs use python. As python evolves a lot and is extensible through modules, it is very frequent that a user do not have the correct modules / modules versions he needs for his project.
To keep it clean and flexible, we do not want to install python packages at the system level, we want each non-privileged user to be using python virtual environment. Note that the base python version requested by the user will need to be installed at the system level.


Proxy

Depending on your company, you may need a proxy to be able to install any python version or module:
export https_proxy=http://www-proxy-your_company.com:80


Example

Below example will be using a non-privileged user "frdenis" on the myvm VM.
[frdenis@myvm ~]$ id
uid=1003(frdenis) gid=1003(frdenis) groups=1003(frdenis) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
[frdenis@myvm ~]$
The default python of the system is 3.6.8:
[opc@myvm ~]$ python -V
Python 3.6.8
[opc@myvm ~]$
Python 3.11 will need to be installed as the example will showcase a python3.11 virtual environment:
[opc@myvm ~]$ sudo dnf install -y python3.11 python3.11-pip
. . .
[opc@myvm ~]$ python3.11 -V
Python 3.11.13
[opc@myvm ~]$


Python venv


Check the system python

[frdenis@myvm ~]$ type python
python is /usr/bin/python
[frdenis@myvm ~]$ /usr/bin/python --version
Python 3.6.8
[frdenis@myvm ~]$

Create and activate a venv

We will name this virtual environment "venv" in this example which is the usage.
[frdenis@myvm ~]$ python -V
Python 3.6.8
[frdenis@myvm ~]$ python3.11 -m venv venv             <== the second "venv" is the name of your venv
[frdenis@myvm ~]$ source venv/bin/activate
(venv) [frdenis@myvm ~]$ python -V            <== note that starting "(venv)" showing you are IN the virtual env
Python 3.11.13
(venv) [frdenis@myvm ~]$

Install packages in the venv

Once the venv activated, we can install any module we want in it and as our non-privileged user:
(venv) [frdenis@myvm ~]$ python
Python 3.11.13 (main, Apr 27 2026, 16:44:16) [GCC 8.5.0 20210514 (Red Hat 8.5.0-28.0.1)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy                               <== numpy is not default
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'numpy'
>>> quit()
(venv) [frdenis@myvm ~]$ export https_proxy=http://www-proxy-hqdc.us.oracle.com:80
(venv) [frdenis@myvm ~]$ pip install numpy
Collecting numpy
  Downloading numpy-2.4.6-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (16.9 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 16.9/16.9 MB 9.2 MB/s eta 0:00:00
Installing collected packages: numpy
Successfully installed numpy-2.4.6
[notice] A new release of pip available: 22.3.1 -> 26.2.1
[notice] To update, run: pip install --upgrade pip
(venv) [frdenis@myvm ~]$ python
Python 3.11.13 (main, Apr 27 2026, 16:44:16) [GCC 8.5.0 20210514 (Red Hat 8.5.0-28.0.1)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy
>>>

Showcase

Let's write a simple python script using numpy:
[frdenis@myvm ~]$ cat test_env.py
import sys
import numpy as np
print("Python Version :", sys.version.split()[0])
print("Numpy Version  :", np.__version__)
print("Numpy Test     :", np.array([10, 20, 30]) * 2)
[frdenis@myvm ~]$
It works in the venv:
(venv) [frdenis@myvm ~]$ python test_env.py
Python Version : 3.11.13
Numpy Version  : 2.4.6
Numpy Test     : [20 40 60]
(venv) [frdenis@myvm ~]$
But not outside of the venv (as numpy is not default) and has only been installed in the venv:
(venv) [frdenis@myvm ~]$ deactivate
[frdenis@myvm ~]$ python test_env.py
Traceback (most recent call last):
  File "test_env.py", line 2, in <module>
    import numpy as np
ModuleNotFoundError: No module named 'numpy'
[frdenis@myvm ~]$


Automatically use the venv

As it may not be nice to source the venv each time we want to run a python script (from a shell for example), 2 solutions exist for that:

Run the script using the venv python

[frdenis@myvm ~]$ ~/venv/bin/python test_env.py
Python Version : 3.11.13
Numpy Version  : 2.4.6
Numpy Test     : [20 40 60]
[frdenis@myvm ~]$

Use a shebang which points to the venv

[frdenis@myvm ~]$ cat test_env.py
#!/home/frdenis/venv/bin/python                             <== here, this is the shebang, adapt to your path
import sys
import numpy as np
print("Python Version :", sys.version.split()[0])
print("Numpy Version  :", np.__version__)
print("Numpy Test     :", np.array([10, 20, 30]) * 2)
[frdenis@myvm ~]$ chmod u+x test_env.py                   <== has to be done only once when setting it up
[frdenis@myvm ~]$ ./test_env.py
Python Version : 3.11.13
Numpy Version  : 2.4.6
Numpy Test     : [20 40 60]
[frdenis@myvm ~]$


Transfer a venv to another user/machine

Note: Do NOT copy the "venv" directory to another user or machine, it contains hardcoded absolute paths and machine specifics which wont make it work.

Export the module list

[frdenis@myvm ~]$ source venv/bin/activate
(venv) [frdenis@myvm ~]$ pip freeze > requirements.txt
(venv) [frdenis@myvm ~]$ cat requirements.txt
numpy==2.4.6
(venv) [frdenis@myvm ~]$

Re-apply to another virtual env

Once this requirements.txt file has been transferred:
[new_user@another_vm ~]$ python3.11 -m venv new_venv             <== create a new venv
[new_user@another_vm ~]$ source new_venv/bin/activate            <== activate the new venv
[new_user@another_vm ~]$ pip install -r requirements.txt         <== reinstall the modules from the original venv
. . .
[new_user@another_vm ~]$

No comments:

Post a Comment

Python venv

A lot of application running on our VMs use python. As python evolves a lot and is extensible through modules, it is very frequent that a u...