#!import using a path relative to the original notebook, rather than relative to the current working directory
Is your feature request related to a problem? Please describe. With #!import, I can import a notebook, even with a relative path.
#!import "../common/library/repo.dib"
Usually, the current working directory (Directory.GetCurrentDirectory()) corresponds to the directory which contains the notebook.
But when I import a notebook containing a relative reference to another notebook, due to the current working directory being different, the relative path no longer works (see example).
I wrote down an example:
- folder1/A.dib
- #!import ../B.dib
- folder2/B.dib
- #!import C.dib
- folder2/C.dib
In this example, I can run B, and it imports C. But if I run A, it imports B, and fails to import C.
In this kind of situation, Jupyter Notebook users usually change the current working directory to the folder of the file. It looks like the following:
- folder1/A.dib
- #!import ../B.dib
- folder2/B.dib
- cd folder2
- #!import C.dib
- folder2/C.dib
It's not good, as it changes the current working directory, affecting the process.
Describe the solution you'd like I would like a parameter to specify that the path is relative to the directory of the notebook which contains the cell.
#!import --relativeToThisNotebookDirectory ../C.dib
Or I would like some kind of variable to express the path of the notebook file path or its directory.
#!import __this_notebook_directory__/../C.dib
Jupyter Notebooks have a variable file, which contains the file path of the actual notebook (the availability of file depends on the implementation of the platform). We also could have a directory variable, which contains the directory path of the actual notebook.
Any working solution is important to me, as I have often the need to chain several notebooks together.
Describe alternatives you've considered
- Using absolute paths to load secondary notebooks
- Changing current working directory
EDIT: see workaound here: https://github.com/dotnet/interactive/issues/3329#issuecomment-3355417449
Looking forward for this feature!
I also encounter this behavior. I consider this as a bug, to be honest.
Hello, I would like to update this issue with a few notes, explaining how this issue is a major obstacle to the creation of shared notebooks (as those shared notebooks cannot import each other).
As the import path is relative to the first notebook executed, it means that when a sub-notebook need to import a notebook, the path must be relative to the first notebook. So the sub-notebook contains a path that is incorrect for itself.
Here is an example:
- first_notebook.dib
- #!import subfolder/sub_notebook_1.dib
- sub_folder/sub_notebook_1.dib
- #!import subfolder/sub_notebook_2.dib
- sub_folder/sub_notebook_2.dib
Here, first_notebook imports sub_notebook_1, and sub_notebook_1 imports sub_notebook_2. But if I run sub_notebook_1 first, it cannot import sub_notebook_2.
This is a huge problem for us. When we are working with Polyglot Notebooks, we are forced to either:
- put all notebooks in the same folder
- put all sub notebooks in a hierarchy of folders, but sub notebooks cannot import each other
It is particularly painful when we have dedicated notebooks containing helpers needing each other, such as a "library/api.dib" that needs "library/json.dib".
Would it be possible to implement one of those solution?
- having a magic parameter / variable corresponding to "the directory of this notebook"
-
#!import --relativeToThisNotebookDirectory other_sub_notebook.dib -
#!import __this_notebook_directory__/other_sub_notebook.dib)
-
- considering the current beahvior as a bug, and making it so all notebooks always import notebooks relative to their current path
For anyone interested, we found a workaround.
We have:
- a main directory, containing our most important entry notebooks, called "main_directory"
- a library sub directory, containing helpers
- a data sub directory
- other directories containing loosely related notebooks, anywhere on the computer
Notebooks in the main directory are calling librairies using relative paths.
#!import "library/my_helper.dib"
All notebooks who need to call a library, or use the data directory, uses this code as first line:
if (System.IO.Directory.GetCurrentDirectory().EndsWith("main_directory") == false) System.IO.Directory.SetCurrentDirectory("path_to_main_directory");
The path to the main directory is either relative or absolute. What is important is that all notebooks set their current directory to the main directory, so they can import librairies, use the data directory, but also call other notebooks that need to fake their position in the main directory as well. It also allows our library notebooks to import each other, as the current directory is always the main directory (and no longer the directory containing the library).
The downside is relatively small: the main directory needs a unique name. If a unique name cannot be used (because notebooks are inside different folders with the same name), then absolute paths can be used.
if (System.IO.Directory.GetCurrentDirectory() != @"C:\my_repo\common_name") System.IO.Directory.SetCurrentDirectory( @"C:\my_repo\common_name");
I hope it will help others.