32

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.

---Update---------

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 cded into WorkingDirectory and started the server there. The working directory should be the folder containing my package.

Ryan
  • 920
  • 3
  • 15
  • 25
  • Possible duplicate of ["ImportError: No module named" when trying to run Python script](http://stackoverflow.com/questions/15514593/importerror-no-module-named-when-trying-to-run-python-script) – Louise Davies Mar 30 '17 at 15:44
  • @LouiseDavies I updated my question to address the duplicate issue. – Ryan Mar 30 '17 at 16:15
  • 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. – reim Aug 17 '19 at 14:57

5 Answers5

24

I'm pretty sure this issue is related and the answer there will help you: https://stackoverflow.com/a/15622021/7458681

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

Community
  • 1
  • 1
Louise Davies
  • 12,825
  • 5
  • 38
  • 40
  • 2
    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? – Ryan Mar 30 '17 at 16:04
3

two lines of code will solve this,

#list the current work dir
os.getcwd()
#change the current work dir
os.chdir()

change the path, and import module, have fun.

noy L
  • 144
  • 1
  • 4
2

if you face module not found on jupyter environment you had to install it on jupyter environment instead of installing it on 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 put ( ! ) before your command.

  • 1
    Please don't post duplicate answers on multiple questions ([here](https://stackoverflow.com/a/68323070/3749896) and [here](https://stackoverflow.com/a/68322977/3749896)). One answer is fine. See [Is it acceptable to add a duplicate answer to several questions?](https://meta.stackexchange.com/questions/104227/is-it-acceptable-to-add-a-duplicate-answer-to-several-questions) – Sven Eberth Jul 09 '21 at 22:27
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.

Jeremy Caney
  • 6,191
  • 35
  • 44
  • 70
-1

The reason is that your MyPackage/__init__.py is ran 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.


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