Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The imgaug 0.4.0 wheel on PyPI has opencv-python (and not opencv-python-headless) as a dependency. #737

Open
creafz opened this issue Dec 9, 2020 · 3 comments

Comments

@creafz
Copy link

creafz commented Dec 9, 2020

Hey, @aleju.
Thank you for your work on imgaug. I am a maintainer of Albumentations, a library that depends on imgaug, and we have a problem that results in the dual installation of both opencv-python and opencv-python-headless. Below is a detailed description of the problem and a proposed solution.

The problem

When I create a clean environment (an environment that doesn't contain an installed OpenCV library) and run the command pip install imgaug to download an imgaug wheel, imgaug requests opencv-python and not opencv-python-headless as its dependency.

This problem doesn't occur when I use the command pip install imgaug --no-binary imgaug to download a source distribution of imgaug.

Why this happens

There are two widespread distribution formats for Python libraries: source distribution and wheel. For source distribution, Python downloads the packaged code and executes setup.py on a user machine to install the library. So this code from setup.py is executed on the user's machine, and it decides whether imgaug should require opencv-python-headless (the default option) or any alternative OpenCV library if that alternative library is already present in the user's environment.

On the contrary, wheels don't contain a setup.py file. So the code inside setup.py is executed only once at the time when the wheel file is being built. So during this build step, setup.py creates a list of imgaug dependencies, and these dependencies are put inside a wheel file as metadata.

I don't know why the imgaug wheel on PyPI requires opencv-python and not opencv-python-headless, but I assume it happens because the ImgAug wheel was built in a Python environment that contained opencv-python. So during the build time, setup.py detected opencv-python and put it (an not opencv-python-headless) as imgaug dependency.

Why this behavior is problematic for Albumentations

Wheel is a preferred distribution format, so pip chooses it by default (the --no-binary flag could disable this behavior). Since wheel doesn't execute setup.py on a client's machine during the installation, there is no way to choose the OpenCV version dynamically.

Albumentations depends on imgaug. The Albumentations wheel has opencv-python-headless as a requirement. Because the ImgAug wheel requires opencv-python when a user installs Albumentations, both opencv-python-headless and opencv-python are downloaded and installed in the user environment simultaneously.

How this problem could be solved

I took a look into the commit history of imgaug, and I assume that opencv-python-headless is a default OpenCV requirement for ImgAug since 0.3.0, and the current behavior of imgaug wheel on PyPI is indeed a bug.

There is no need to change the code to make the imgaug wheel always require opencv-python-headless. It is enough to build wheels for imgaug in a clean environment that doesn't have OpenCV installed.

This GitHub workflow already builds wheels with the opencv-python-headless dependency, so it is enough to upload to PyPI wheels produced by it to fix the problem described in this issue.

Additional note on why Albumentations uses opencv-python-headless instead of opencv-python by default.

Albumentations is often used inside environments (e.g. Docker containers) that don't contain GUI libraries since the user code doesn't need them. But if someone tries to use opencv-python in those environments, she will get an exception like "ImportError: libGL.so.1: cannot open shared object file: No such file or directory".

There is, of course, exists a workaround. A user could add those shared libraries for GUI support into the environment by building a new Docker image. However, this action will result in larger images containing unnecessary libraries.

So as a reasonable default, we chose opencv-python-headless that doesn't require those GUI libraries to work.

@bertsky
Copy link

bertsky commented Dec 10, 2020

Duplicate of #473.

@jspaezp
Copy link

jspaezp commented Mar 3, 2021

@creafz Has there been any discussion in albumentations about the future of this project?

I feel like "it works" for now but I am not sure if @aleju will be able to maintain it going forward (based exclusively on the lack of activity on his account)

@creafz
Copy link
Author

creafz commented Mar 3, 2021

Hey @jspaezp

Yes, there was an internal discussion in Albumentations, but it was related more to what to do with imgaug as a dependency. Albumentations uses 10 augmentations from imgaug (they are all located in albumentations/imgaug/transforms.py), and we decided to reimplement them in OpenCV but if possible to keep the same API. This change will help us better control the internals Albumentations and its distribution. Then we plan to stop using imgaug as a dependency.

As for the future of imgaug, if @aleju wants, we can discuss whether the Albumentations team could help with imgaug but I am afraid that we do not have enough resources for helping to maintain imgaug along with Albumentations.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants