Proper way to install Python modules?

Hello,

I’m dabbling with this Python module:

The only way I can get pip to install it on the Le Potato /w headless Raspbian is with this command:

pip3 install --break-system-packages adafruit-circuitpython-bno055

I would create a virtual python environment and use that instead, but I can’t figure out how to add the correct gpiod module into the virtual environment. This is the one that is already pre-installed in the Raspbian image.

I’ve tried making a virtual environment as such:

python3 -m venv tankbot
source tankbot/bin/activate
pip3 install gpiod

But, this is not the right gpiod. I have scripts that work with the pre-installed gpiod module. But when I activate this python virtual environment, I get errors.

from gpiod import Chip, LINE_REQ_DIR_OUT, LINE_REQ_DIR_IN
ImportError: cannot import name 'LINE_REQ_DIR_OUT' from 'gpiod' (/root/tankbot/lib/python3.11/site-packages/gpiod/__init__.py)
  1. What’s the right way to install python modules?
  2. How do I install the the correct gpiod module into a python virtual environment? “The correct gpiod” being the problem, not the creation of the virtual environment.

There’s already a bno055 driver in Linux. There’s no reason to use a hacked userspace driver and manually bitbang the bus like the adafruit library does.

https://docs.kernel.org/iio/bno055.html

You should use the libretech-wiring-tool to create a device-tree overlay that maps the sensor to a GPIO instead.

The need to install other python packages persists, though. How can one safely install other python packages? Or, how can one install the correct “gpiod” within a python virtual environment?

Here are the two methods I’ve come up with for using the proper gpiod python package - the one that ships with the copy of Le Potato Raspbian 12.

Easy Way, Symlink It.

First, I needed to determine where the package is. Below is a python script that you’d run using the Python environment that ships with the Le Potato Raspbian 12. It’ll print the location of the gpiod package.

def main():
    # Try importing gpiod
    try:
        import gpiod
    except ImportError:
        print("gpiod is not installed or cannot be found.")
        return

    # Print out where Python is loading gpiod from
    print(f"Path to gpiod module: {gpiod.__file__}")

if __name__ == "__main__":
    main()

Running the above script gives the below output on Le Potato Raspbian 12:

Path to gpiod module: /usr/lib/python3/dist-packages/gpiod.cpython-311-aarch64-linux-gnu.so

Using this information, we can symlink this into a python virtual environment.

Make a virtual environment located here: ~/my_project_env and activate it:

python3 -m venv ~/my_project_env
source ~/my_project_env/bin/activate

Determine where you need to make your site-packages directory.

ls ~/my_project_env/lib
python3.11

In this case it’s python3.11

Make your site packages directory:

mkdir -p ~/my_project_env/lib/python3.11/site-packages

Create a symlink from the correct gpiod package to your virtual environment’s site packages.

ln -s /usr/lib/python3/dist-packages/gpiod.cpython-311-aarch64-linux-gnu.so ~/my_project_env/lib/python3.11/site-packages/

Using your virtual environment, test that gpiod imports correctly.

python -c "import gpiod; print(dir(gpiod))"
['Chip', 'ChipIter', 'LINE_REQ_DIR_AS_IS', 'LINE_REQ_DIR_IN', 'LINE_REQ_DIR_OUT', 'LINE_REQ_EV_BOTH_EDGES', 'LINE_REQ_EV_FALLING_EDGE', 'LINE_REQ_EV_RISING_EDGE', 'LINE_REQ_FLAG_ACTIVE_LOW', 'LINE_REQ_FLAG_BIAS_DISABLE', 'LINE_REQ_FLAG_BIAS_PULL_DOWN', 'LINE_REQ_FLAG_BIAS_PULL_UP', 'LINE_REQ_FLAG_OPEN_DRAIN', 'LINE_REQ_FLAG_OPEN_SOURCE', 'Line', 'LineBulk', 'LineEvent', 'LineIter', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '__version__', 'find_line', 'version_string']

The above will allow you to use the pre-installed gpiod package in a python virtual environment.

Build From Source Code

If you want to build from source on the Le Potato Raspbian 12, these are the needed build dependencies:

sudo apt-get update
sudo apt-get install \
    autoconf automake libtool pkg-config \
    autoconf-archive \
    build-essential \
    python3-dev python3-setuptools python3-wheel

Clone the source repository and enter the directory:

git clone https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git
cd libgpiod

Make a distinctively named Python virtual environment where you’ll set things up:

python3 -m venv ~/venv_with_gpiod_from_source
source ~/venv_with_gpiod_from_source/bin/activate

Verify your virtual environment environment variable is set correctly:

echo $VIRTUAL_ENV
/root/venv_with_gpiod_from_source

Install Python’s build package into your virtual environment.

pip install build

Run the repo’s bootstrap script (this will take a while).

./autogen.sh

Configure the files to use your python virtual environment.

./configure --prefix="$VIRTUAL_ENV" --enable-bindings-python

Run make and make install (Also takes a while):

make
make install

Set your LD_LIBRARY_PATH environment variable to properly use your virtual environment:

export LD_LIBRARY_PATH="$VIRTUAL_ENV/lib:$LD_LIBRARY_PATH"

Test it:

python -c "import gpiod; print(dir(gpiod))"
['Chip', 'ChipClosedError', 'ChipInfo', 'EdgeEvent', 'InfoEvent', 'Iterable', 'LineInfo', 'LineRequest', 'LineSettings', 'Optional', 'RequestReleasedError', 'Union', '__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', '__version__', '_ext', '_internal', 'api_version', 'chip', 'chip_info', 'edge_event', 'exception', 'info_event', 'is_gpiochip_device', 'line', 'line_info', 'line_request', 'line_settings', 'request_lines', 'version']