Python venvs and the Yoctopuce library

Python venvs and the Yoctopuce library

Our customers widely use the Python language, particularly on the Raspberry Pi. One of Python's strengths is the Python Package Index (PyPI) repository, which makes it easy to use a large number of libraries, including the Yoctopuce library. However, some recent Linux distributions block the use of this repository if not using a venv.




In our Python tutorial, we explain that it's enough to use the "pip install yoctopuce" command to install our library on a machine. However, if we run this command on a freshly installed Raspberry Pi, here's the result:

yocto@rpi:~ $ pip install yoctopuce error: externally-managed-environment × This environment is externally managed ╰─> To install Python packages system-wide, try apt install python3-xyz, where xyz is the package you are trying to install. If you wish to install a non-Debian-packaged Python package, create a virtual environment using python3 -m venv path/to/venv. Then use path/to/venv/bin/python and path/to/venv/bin/pip. Make sure you have python3-full installed. For more information visit http://rptl.io/venv Note: If you believe this is a mistake, please contact your Python installation or OS distribution provider. You can override this, at the risk of breaking your Python installation or OS, by passing --break-system-packages. hint: See PEP 668 for the detailed specification.


This message appears in some recent Linux distributions such as Debian, Ubuntu and their derivatives.

What's a venv?

A Python venv (virtual environment) is an isolated space where Python packages can be installed without affecting the rest of the system. This system was introduced with Python 3.3 and avoids conflicts between different versions of packages used by Python applications. Instead of having a global environment for the whole machine, you create an environment per project.

So how do you install the Yoctopuce library (or any other library) using pip?

Creating a virtual environment

The recommended option is to create a venv for the project.

To illustrate the use of venv, we'll use a basic example that lists the Yoctopuce modules connected to the USB port and save the code in the ~/test/inventory.py file.

from yoctopuce.yocto_api import *

errmsg = YRefParam()
if YAPI.RegisterHub("usb", errmsg) != YAPI.SUCCESS:
    sys.exit("init error" + str(errmsg))

print('Device list')
module = YModule.FirstModule()
while module is not None:
    print(module.get_serialNumber() + ' (' + module.get_productName() + ')')
    module = module.nextModule()
YAPI.FreeAPI()


We then need to create a venv, which we store in the ~/yocto_venv directory with the following command:

yocto@rpi:~/test $ python -m venv ~/yocto_venv


This creates a ~/yocto_venv directory containing an isolated version of Python and pip.

To use this virtual environment, you activate it with the following command:

yocto@rpi:~/test $ source ~/yocto_venv/bin/activate (yocto_venv) yocto@rpi:~/test $ source


As you can see, the shell has been modified to use the Python version and virtual environment packages.

Under Linux, this can easily be verified using the which command.

yocto@rpi:~/test $ which python /usr/bin/python yocto@rpi:~/test $ source ~/yocto_venv/bin/activate (yocto_venv) yocto@rpi:~/test $ which python /home/yocto/yocto_venv/bin/python


When the virtual environment has been activated, you can install the Yoctopuce library using pip:

(yocto_venv) yocto@rpi:~/test $ pip install yoctopuce Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple Collecting yoctopuce Using cached https://www.piwheels.org/simple/yoctopuce/yoctopuce-2.0.63620-py2.py3-none-any.whl (5.4 MB) Installing collected packages: yoctopuce Successfully installed yoctopuce-2.0.63620


The library is installed in the ~/yocto_venv directory and can only be used in this virtual environment.

yocto@rpi:~/test $ python inventory.py


Using the environment without activating it

Note that it's also possible to use the virtual environment directly without having to activate it. Simply use the Python or pip executable stored in the virtual environment directory:

yocto@rpi:~/test $ ~/yocto_venv/bin/python inventory.py


Using USB ports

If you use our library to connect to a YoctoHub or VirtualHub, everything works without a hitch. But if you're using modules connected to USB ports, there's one more detail to consider.

Under Linux, write access to USB ports is blocked for "non-root" users. And YAPI.RegisterHub() returns the error message: "the user has insufficient permissions to access USB devices".

There are two ways to work around this problem.

The first is to install an udev rule to authorize all users to access Yoctopuce modules. This procedure is explained in our modules' documentation and does not cause any problems with venv.

The other solution is simply to run the Python program as root using the sudo command. But this solution has a pitfall when used with venv: venv activation doesn't work, so you need to use the Python or pip executable stored in the virtual environment directory.

For example, the following code doesn't work, because the sudo command uses the system Python and not the venv Python.

yocto@rpi:~/test $ source ~/yocto_venv/bin/activate yocto@rpi:~/test $ sudo python inventory.py Traceback (most recent call last): File "/home/yocto/test/inventory.py", line 1, in <module> from yoctopuce.yocto_api import * ModuleNotFoundError: No module named 'yoctopuce'


But if you pass the full path of the Python executable, it works:

yocto@rpi:~/test $sudo ~/yocto_venv/bin/python inventory.py Device list MXPWRRLY-45C5B (Yocto-MaxiPowerRelay) METEOMK2-20713E (Yocto-Meteo-V2)


The --break-system-packages option

The other option available is not to use the virtual environment at all and to force the package to be installed globally. In this case, use the --break-system-packages option when installing the Yoctopuce package.

yocto@rpi:~ $ pip install --break-system-packages yoctopuce Defaulting to user installation because normal site-packages is not writeable Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple Collecting yoctopuce Using cached https://www.piwheels.org/simple/yoctopuce/yoctopuce-2.0.63620-py2.py3-none-any.whl (5.4 MB) Installing collected packages: yoctopuce Successfully installed yoctopuce-2.0.63620


The package is installed globally and the library can be used by all Python programs and all users.

Conclusion

This post should clarify the use of the Yoctopuce library with Python virtual environments. There's nothing complicated about it, but it can be a little confusing when you're new to Python programming.

Whether or not to use a Python virtual environment depends above all on your project. If you have several Python applications on your machine, it can help avoid issues with conflicts between libraries. But if you just have a small program you've written on a Raspberry Pi, the --break-system-packages option shouldn't pose any problems and will make your life a lot easier.

Add a comment No comment yet Back to blog












Yoctopuce, get your stuff connected.