System designTroubleshooting

Python camera SDK install script fails under pyenv: use pip directly

When a camera SDK's install script finds no virtualenv under pyenv, run pip against the extracted wrapper folder and land the package in your interpreter.

LumaSpec Vision9 min read Share on LinkedIn

On this page 9 sections
  1. 01What the script actually checks
  2. 02Likely causes, in order of probability
  3. 03The fix: run pip against the wrapper folder
  4. 04Worked example: an SDK 6.0 wrapper on Python 3.7.15, installed without sudo
  5. 05When the import works in one shell and fails in another
  6. 06Wrapper installed, camera still not found
  7. 07Prevention on the next SDK
  8. 08Next step: the camera the wrapper will drive
  9. 09Questions

A camera SDK's Linux install script aborts with a virtual-environment error even though your pyenv environment is active and pip works in the same shell. Nothing is broken on either side. The script's only gate is one environment variable, and the two most common pyenv setups never present it in the form the script expects. This article is for engineers installing a machine-vision SDK's Python wrapper on a Linux workstation. It shows where the check fails, how sudo and plain pyenv each trip it, and the pip command that installs the wrapper into the interpreter you selected — plus the one-line check that proves where the package landed.

What the script actually checks

The helper asks exactly one question about your shell: is VIRTUAL_ENV set to a path? A standard virtualenv answers yes once you run its activate script, and pyenv-virtualenv answers yes after pyenv activate. A plain pyenv version chosen with pyenv local or pyenv global never answers yes — pyenv swaps the interpreter without pretending to be a virtualenv.

sudo fails that question from the other side. It resets most of the environment a command inherits and replaces PATH with a short list, so an activated environment arrives at the script invisible. On the failing machine the script printed 'No virtual environment detected', searched /sbin, /bin, /usr/sbin and /usr/bin — the reduced PATH sudo handed it — and aborted with 'No compatible Python version with pip support found', because the pyenv shims that resolve python and pip live under your home directory, outside that list.

So one message covers two failure modes: sudo stripped an environment that was genuinely set, or no activated virtualenv ever existed because plain pyenv selection was doing the work. The two tests in the next section separate them in under a minute.

Likely causes, in order of probability

Run two commands in the shell you launched the script from, before changing anything: echo $VIRTUAL_ENV and pyenv version. The table maps the three possible outcomes to the fix for each.

# Cause Test Fix
1 sudo reset the environment, so VIRTUAL_ENV and your PATH never reached the script echo $VIRTUAL_ENV prints a path in your shell, yet the script run with sudo reports none stop running the helper under sudo; install with pip as your user (next section)
2 a plain pyenv version is selected, so no virtualenv is active and VIRTUAL_ENV is empty echo $VIRTUAL_ENV prints nothing while pyenv version prints, for example, 3.7.15 skip the helper; the pyenv shim, not the script, picks the interpreter
3 the shims are missing from PATH in this shell which python does not point into ~/.pyenv/shims re-source pyenv's shell init or open a new login shell, then install

Cause 1 is the most common in the field, because running installers with sudo is a habit carried over from system packages. Cause 2 is the plain pyenv behaviour the helper was never written for, which is why the vendor now points users at pip itself.

The fix: run pip against the wrapper folder

For this case the vendor's guidance is short: the script exists for people who prefer not to drive pip, and installation is done by executing pip install with the path of the extracted wrapper folder. Pip installs into the site-packages of whichever interpreter the pip command targets, and under pyenv the shim chooses that interpreter for you. Work through the following as your ordinary user, from the folder where the version is selected.

  1. Confirm the interpreter: run pyenv version; expect 3.7.15 (set by /home/you/project/.python-version), and python -V printing Python 3.7.15.
  2. Confirm pip belongs to the same interpreter: pip --version must report a path ending in .../versions/3.7.15/... with the tag (python 3.7).
  3. If the wrapper's manual pins a pip version, install that pip into this same interpreter first — the FAQ gives the one-liner for the pinned 21.1.2 case.
  4. Install without sudo: python -m pip install ./path-to-wrapper, where path-to-wrapper stands for the wrapper directory inside your extracted SDK tree, the one that contains setup.py. The python -m form binds pip to the interpreter you just confirmed, so the target cannot drift.
  5. Confirm the landing: python -m pip show <wrapper-package>; the Location line must start with ~/.pyenv/versions/3.7.15/. Substitute the package name the wrapper's documentation specifies.

The whole sequence, with the outputs that matter:

pyenv version        # 3.7.15 (set by /home/you/project/.python-version)
python -V            # Python 3.7.15
pip --version        # pip 21.1.2 from ~/.pyenv/versions/3.7.15/lib/python3.7/site-packages/pip (python 3.7)
python -m pip install ./path-to-wrapper
python -m pip show <wrapper-package>
# Location: /home/you/.pyenv/versions/3.7.15/lib/python3.7/site-packages

Worked example: an SDK 6.0 wrapper on Python 3.7.15, installed without sudo

Inputs, each from the failing install: interpreter Python 3.7.15, built by pyenv and selected with pyenv local 3.7.15 in the project folder; pip 21.1.2, the version the wrapper's manual requires; wrapper source is the Python wrapper folder inside the extracted SDK 6.0 tree; the failed attempt was the helper run with sudo from an activated pyenv environment.

Rule: pip installs into the site-packages of the interpreter that runs it, and the pyenv shim resolves a command in the order shell setting, local setting, global setting, system Python.

The resolution, step by step:

  1. No pyenv shell version is set in this shell, so the first rule does not apply.
  2. The working directory contains a .python-version file reading 3.7.15, so both python and pip resolve to ~/.pyenv/versions/3.7.15/bin.
  3. pip --version confirms the pairing: pip 21.1.2 from ~/.pyenv/versions/3.7.15/lib/python3.7/site-packages/pip (python 3.7). The 3.7.15 interpreter owns a python3.7 tree, and the trailing tag names the same minor version — matched.
  4. python -m pip install ./path-to-wrapper therefore builds and installs into that python3.7 site-packages, under your own user.
  5. python -m pip show reports Location: ~/.pyenv/versions/3.7.15/lib/python3.7/site-packages — the same tree as steps 3 and 4.

Decision: a Location under ~/.pyenv/versions/3.7.15/ means the wrapper is bound to the interpreter you selected — import it and enumerate cameras. A Location under /usr/lib/python3 or /usr/local/lib/python3 means the system interpreter received the package because the shims did not lead PATH: fix the shell's pyenv init and reinstall. Any sudo in this chain re-breaks step 2, because sudo strips VIRTUAL_ENV and shortens PATH — so the whole example runs as your own user.

When the import works in one shell and fails in another

A package exists only in the site-packages of the interpreter whose pip installed it. The same trap appears in reverse: a module that imports outside an environment but not inside it was installed into the system interpreter, and the environment's interpreter never saw it. Diagnose from the failing shell, not the working one. Run python -m pip show with the wrapper's package name there. An empty result means that interpreter does not own the package — switch with pyenv local or pyenv global to the version that does, or install again from that shell. The deeper version of this problem, a GenICam package that will not install or import against the interpreter you meant, is worked through in GenICam Python package not found: match your interpreter.

Wrapper installed, camera still not found

Pip installs Python code; it does not install the SDK's native runtime, its device rules or its driver package. A wrapper that imports cleanly but returns an empty device list is pointing at those layers, not at the install you just fixed. Work them in order: check the driver side with camera driver package not configured: restore camera detection; if a device is detected but the first read fails, first GenTL read always fails: fix the initial camera I/O error covers the transport layer. Also confirm generation match: a wrapper built against one SDK generation will not drive a runtime of another — Wrong SDK for the camera: fix the driver family mismatch shows how to pair them.

Prevention on the next SDK

  • Run every SDK helper as your ordinary user; reserve sudo for the runtime components that truly write system files.
  • Select the interpreter with pyenv local per project folder, so the choice travels with the project in .python-version instead of living in one shell.
  • Prefer python -m pip over bare pip for SDK installs.
  • After any SDK install, read the Location line from python -m pip show before the first import — one line that exposes a wrong-interpreter install immediately.
  • Record the wrapper version and the runtime version together when a bench works, so a later upgrade cannot mix generations silently.

More driver, build and SDK fixes sit on the systems topic page.

Next step: the camera the wrapper will drive

With the wrapper importing and enumerating, the remaining choices are the camera and the optics around it. Browse the area scan cameras category or filter by interface and resolution in the camera finder; the camera step of the configurator pairs the camera with lens and cable in one pass. For an install that still resists, the contact page reaches the applications team.

CamerasArea scan cameras

GigE, USB3, 10GigE and CoaXPress

1,287 models · from $149.00

Questions

Why does the SDK ship an install script at all if pip does the job?

You can leave it where it is and ignore it. The helper configures nothing persistent: each run only inspects the environment and then drives a pip install. Deleting it changes nothing about a wrapper already installed with pip, and keeping it costs nothing for colleagues who prefer the guided path on a plain virtualenv.

When is sudo actually needed around a camera SDK install?

Two places, and neither is the wrapper. The SDK's native runtime or its device rules may write system files, and that step can need administrator rights — the SDK documentation says which parts. The Python wrapper never does: a pyenv build lives under your home directory, so pip writes there with your own rights. If an instruction demands sudo for the wrapper itself, it assumes a system Python, not a pyenv interpreter.

How do I keep several SDK wrappers, each with its own Python?

Give each project folder its own selection: run pyenv local 3.7.15 in one and pyenv local 3.11.8 in another; each command writes a .python-version file in that folder. Every shell you open there resolves python and pip to that version through the shims. Install each SDK wrapper from inside its own folder, and pip show's Location line records which tree owns it.

Can I keep the pip version the SDK manual pins?

Yes. Install the pinned pip into the same interpreter first — python -m pip install pip==21.1.2 for the 21.1.2 pin — then install the wrapper immediately after. The build uses whichever pip belongs to the interpreter running the command, so the pin holds for as long as you work inside that pyenv version.

Does the same failure appear on other Linux distributions?

The mechanism is identical wherever pyenv and pip run: any helper keyed on VIRTUAL_ENV reads the same variable, and sudo strips the same names from the environment everywhere. What differs is the system layout — one family keeps Python under /usr/lib, another under /usr/local — so the Location line from pip show, not the distribution name, is what tells you where a package actually landed.