Module not found during import in Jupyter Notebook
Asked Answered
C

9

47

I have the following package (and working directory):

WorkingDirectory--
                 |--MyPackage--
                 |            |--__init__.py
                 |            |--module1.py
                 |            |--module2.py
                 |
                 |--notebook.ipynb

In __init__.py, I have:

import module1
import module2

If I try to import MyPackage into my notebook:

import MyPackage as mp

I will get

ModuleNotFoundError: No module named 'module1'

But import works fine if I execute the script outside a notebook: if I create test.py in the same directory and do the same as in the notebook the import would work properly. It will work inside the notebook if I use fully qualified name in __init__.py (import MyPackage.module1).

What's the reason for different import behavior?

I have confirmed the working directory of the notebook is WorkingDirectory.

The exact error is:

C:\Users\Me\Documents\Working Directory\MyPackage\__init__.py in <module>()
---> 17 import module1

ModuleNotFoundError: No module named 'module1'

My problem differs from the possible duplicate:

  1. The notebook was able to find the package, but only unable to load the module. This was inferred from substituting module1 with MyPackage.module1 worked well and suggests it may not be a problem related with PATH.

  2. I cd'ed into WorkingDirectory and started the server there. The working directory should be the folder containing my package.

Confute answered 30/3, 2017 at 13:59 Comment(4)
Possible duplicate of "ImportError: No module named" when trying to run Python scriptSaransarangi
@LouiseDavies I updated my question to address the duplicate issue.Confute
I have had a similar issue where it was connecting to some old kernel which did not have all of the packages; make sure you have one at a time and that it connects to the default port, 8888.Enlistment
https://mcmap.net/q/94875/-jupyter-modulenotfounderror-no-module-named-matplotlib worked for meConstitutive
S
35

I'm pretty sure this issue is related and the answer there will help you: "ImportError: No module named" when trying to run Python script

tl;dr: the cwd of the notebook server is always the base path where you started the server, no matter was running import os os.getcwd() says. Use import sys sys.path.append("/path/to/your/module/folder").

I ran it with some dummy modules in the same structure as you had specified, and before modifying sys.path it wouldn't run and after it would.

Saransarangi answered 30/3, 2017 at 15:34 Comment(1)
Do you mean to add WorkingDirecotry to PATH or WorkingDirectory/MyPackage? The latter worked but the former didn't. Is that the expected behavior? And if the PATH is where the problem lies, why does using fully qualified name in init.py solve the problem?Confute
A
7

Understand these two functions, and your problem will be solved.

# List the current work directory
os.getcwd()

# Change the current work directory
os.chdir()

Change the path, and import module, and have fun.

Sometimes it won't work. Try this:

import sys
# 'sys.path' is a list of absolute path strings
sys.path.append('/path/to/application/app/folder')

import file
Arlenearles answered 6/7, 2020 at 1:49 Comment(2)
os.chdir requires a parameterTribunal
Error: NameError Traceback (most recent call last) Cell In[2], line 1 ----> 1 os.getcwd()Chapen
K
5

The best way to tackle this issue is to create a virtual env and point your kernel to that virtual environment:

Steps:

  1. python -m venv venv
  2. source venv/bin/activate
  3. ipython kernel install --user --name=venv
  4. jupyter lab
  5. go to the jupyter lab ->kernel-->change kernel-->add the venv from the dropdown

Now if your venv has the package installed, JupyterLab can also see the package and will have no problem importing the package.

Keikokeil answered 27/6, 2022 at 22:45 Comment(1)
This is the most generic solution.Assert
S
3

If you face module not found in a Jupyter environment, you had to install it on a Jupyter environment instead of installing it on the command prompt.

By this command (for Windows) on Jupyter

!pip install module name

After that, you can easily import and use it. Whenever you want to tell Jupyter that this is system command, you should prepend ( ! ) before your command.

Selfabsorbed answered 9/7, 2021 at 22:19 Comment(2)
Please don't post duplicate answers on multiple questions (here and here). One answer is fine. See Is it acceptable to add a duplicate answer to several questions?Sharpeyed
Re "( ! )": Are the parentheses included? Are the spaces included?Hypothesize
O
1

My problem was that I used the wrong Conda environment when using Visual Studio Code.

Enter your Conda environment:

conda activate **enviroment_name**

To check where a module is installed, you can enter Python interactive mode by writing python or python3. Then importing cv2 (OpenCV 2):

import cv2

Then to see where this module is installed:

print(cv2.__file__)

You will see the installed path of the module. My problem was that my Visual Studio Code kernel was set to the wrong environment. This can be changed in the top right corner for Visual Studio Code.

Overlive answered 28/6, 2022 at 7:40 Comment(0)
G
0

You can do that by installing the import_ipynb package.

pip install import_ipynb

Suppose you want to import B.ipynb in A.ipynb, you can do as follows:

In A.ipynb:

import import_ipynb
import B as b

Then you may use all the functions of B.ipynb in A.

Glycoprotein answered 11/9, 2021 at 0:35 Comment(0)
P
0

This happened to me when I moved my journal into a new directory while the Jupyter lab server was running. The import broke for that journal, but when I made a new journal in the same directory I just moved to and used the same import, it worked.

To fix this, I:

  1. Went to the root directory for my project.
  2. Searched for all folders labeled “pycache
  3. Deleted all “pycache” folders that were found in my root and subfolders.
  4. Restarted the JupyterLab server

Once JupyterLab restarts and compiles your code, the “pycache” folders will be regenerated. Also the pycache folders have two leading and trailing “_”, but Stack Overflow is formatting the pycache’s without them.

Peplum answered 27/10, 2022 at 14:23 Comment(1)
You can escape underscores (_) with backslash.Hypothesize
D
0

The best solution by far (for me) is to have a kernel for each environment you are working in. Then, with that kernel defined, all you have to do is to update this kernel's environment variables to look at your project folder where your modules are located.

Steps (using pip):

  1. pip install ipykernel (if not installed already)
  2. source activate <your environment name>
  3. python -m ipykernel install --user --name <your environment name> --display-name "<a display name>" (where is the name you want to give to your kernel and is just a name used for display by jupyter.
  4. Once you ran the command above, it will output the location of the kernel configuration files. E.g.: C:\Users\<your user name>\AppData\Roaming\jupyter\kernels\<selected environment name>. Go to this folder and open the kernel.json file.
  5. Add the following entry to this file:
"env": {
   "PYTHONPATH": "${PYTHONPATH};<the path to your project with your modules>
 }

Good reference about the kernel install command here.

Denomination answered 29/12, 2022 at 11:27 Comment(0)
P
-1

The reason is that your MyPackage/__init__.py is run from the current working directory. E.g. from WorkingDirectory in this case. It means, that interpreter cannot find the module named module1 since it is not located in either current or global packages directory.

There are few workarounds for this. For example, you can temporarily override a current working directory like this

cwd = os.getcwd()
csd = __path__[0]
os.chdir(csd)

and then, after all a package initialization actions like import module1 are done, restore "caller's" working directory with os.chdir(cwd).

This is quite a bad approach as for me, since, for example, if an exception is raised on initialization actions, a working directory would not be restored. You'll need to play with try..except statements to fix this.

Another approach would be using relative imports. Refer to the documentation for more details.

Here is an example of MyPackage/__init__.py that will work for your example:

from .module1 import *

But it has few disadvantages that are found rather empirically then through the documentation. For example, you cannot write something like import .module1.

I've found this exception to be raised even if import MyPackage is ran from the usual Python console. Not from IPython or Jupyter Notebook. So this seems to be not an IPython itself issue.

Polecat answered 31/1, 2019 at 20:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.