No module named cv2

I am trying to add my plugin that uses opencv and matplotlib libraries. However when I run webodm restart I get the error in the uploaded photo saying

WARNING Failed to instantiate plugin myplugin: No module named ‘cv2’

Is this issue related to python environments etc because when I run import cv2 from my python shell in the WebODM directory it imports without error. How do I solve this?

1 Like

When the worker runs, it runs inside a Docker container, which doesn’t have access to the environment that you have set up for development.

Disclaimer: I don’t know for a fact that the following is correct!

I am guessing from this example that any Python dependency defined by your plugin in requirements.txt would be made available to the worker so that an instance of the plugin can be created.

Does you plugin currently have a requirements.txt file? Is the package that provides cv2 in there? (I’m guessing the package that provides cv2 is opencv-python but I’m sure you’ll know that better than I do.)

1 Like

I add opencv-python to the requirements.txt and ran webodm restart, it still gives the same error (WARNING Failed to instantiate plugin agitated: No module named ‘cv2’). And also some time when I edit the test plugin try to upload it via the dashboard it fails to instantiate the added plugin saying no module named (name of plugin).

In the screenshot in your first post it said:

WARNING Failed to instantiate plugin test1: No module named ‘cv2’
WARNING Failed to instantiate plugin myplugin: No module named ‘cv2’

Note: if agitated, test1 and myplugin are different plugins, they probably all need to have their own requirements.txt. But I suppose you might have been testing and may have renamed your plugin since you took that screenshot.

Are there other errors related to cv2 or opencv?

If opencv-python was in the requirements.txt file and you see no other errors, I would assume that either it was correctly installed, or that putting dependencies in the requirements.txt file of the plugin is not enough for them to be installed in the Docker container.

Without looking at the plugin itself, I don’t know what else to try, so I’ll hope someone more familiar with the ODM plugins’ structure can step in!

I get your point, these were different plugins that I was testing but in all of them I included the requirements.txt. I now don’t understand what is the issue now, some times if I completely restart the project ie cloning it from the repo after removing the docker containers, I can copy the test plugin and successfully import cv2, but when I include the code for my plugin that imports cv2, the plugin itself fails to instantiate saying the is no module named (name of the plugin). Also note that I am uploading these plugins as zip folders in the dashboard since just including the plugin folder inside the coreplugins and running ./webodm restart wont recognize these plugins. Find the sample plugin here: https://drive.google.com/file/d/1RH3HoYrBcnoG8JZi-v4yO7gRd08ydKfm/view?usp=drive_link

This I think is a clue. When you get no module named (name of a dependency, e.g cv2), it relates to requirements.txt.

The module (name of the plugin) wouldn’t be declared in requirements.txt anyway, so even if the error looks similar, I think the cause is different!

1. Hypothesis about where the error happens

Looking at the same example as before, I don’t see any place where I would expect to import (name of the plugin) or from (name of the plugin) import *. Instead, it seems conventional to use from .plugin import * and a plugin.py file inside the plugin package itself.

That makes me think that the error happens outside of your plugin, when some ODM / WebODM code tries to import it. (Given your screenshot, the logs don’t seem to include the location where the error happened, besides saying worker, so we can’t really confirm that.)

2. Why would the new error happen once import cv2 succeeds, though?

If it’s a different error/cause than the no module named 'cv2', then I’d ask myself: did we solve that one, and is this the next step?

In other terms: if two imports where to fail for whatever reason, why would importing a dependency fail first, if importing the plugin was going to fail as well. Why would we try to import the dependency before trying to import the plugin?

I am not sure about that… thinking aloud: if the plugin was not found, the import cv2 would have no reason to be interpreted at all, so we wouldn’t see it fail… I think… but if the plugin was found, then I don’t see why importing the plugin’s package would fail (that is the file (name of the plugin)/__init__.py). :face_with_raised_eyebrow: (I feel like I’m making a mistake / missing something.)

We can test a part of my reasoning:

  • If you rename the directory of your plugin, do you get an error that says no module named (new name)?
  • If you remove the requirements.txt file from your plugin, do you get no module named 'cv2' again?

By the way, it looks like the G. Drive link is not publicly accessible. But I’m not sure you actually want it to be publicly accessible? We should be able to figure this out without the code anyway, no pressure from me on that!

1 Like

If you modify the source of WebODM (e.g. the coreplugins directory) and want those changes to be picked up, I believe you need to re-build the corresponding Docker image, and I don’t believe ./webodm restart would re-build the Docker image. (My guess would be that the command only creates a new container from the existing image, and maybe not even that, I’m not sure!). In all cases, the last part doesn’t look unexpected to me.

Besides, if the Dashboard offers the option of loading plugins as ZIP files, then I would expect that to work with your plugin. I don’t believe the errors you’re seeing are caused by using a ZIP file. :+1:

I’m not sure if the following is exactly what you’re saying, however:

If you can load the test plugin as a ZIP file, but doing the same with yours causes a no module named (name of the plugin) then I wonder if there could be a naming convention that’s missing, e.g. the name of the ZIP file might have to match the name of the plugin, or maybe it’s the name of the directory inside that ZIP file, or whether there is a directory at the root of the ZIP file at all, or if the contents of your plugin must be at the root of the ZIP file… something along those lines. I haven’t found documentation about that, have you found something I missed / are you following any docs I could look at?

I think to reproduce the error you could try running the following plugin now it can be shared:faraiplugin.zip - Google Drive

let me try rebuilding the docker images meanwhile

1 Like

@farai Update, I’m pretty sure what’s happening is that cv2 is still not being imported successfully (or that some other dependency is missing).

I tried loading your plugin, and some copies of the test plugin. There are still things I don’t understand (not all copies of test can be loaded for example), but I found that some of the errors that happen when loading plugins are not printed in the log.

I opened an issue describing that:

Unrelated, but could be useful to know:

You can modify the WebODM code that’s running inside a container while it’s running. The one that loads the plugins is called webapp. What’s interesting is that if you do that, then ./webodm.sh stop, when you ./webodm.sh start again, the same container will be used!

It’s not a long term solution, because that container will eventually get destroyed will all the changes you make to it, but to try things out it’s pretty convenient.

Example, starting bash inside the container:

docker exec -it webapp bash

Among other things, you can run python in the container to verify that you can import cv2.

1 Like

Thanks for opening up the GitHub issue, It seems the issue is bigger. For progress’ & testing sake I will try out your suggestion while keeping an eye on the issue.

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.