Duke3e33
Duke3e33

Reputation: 321

Running one jupyter notebook from another and passing arguments with magic commands

I am unable to pass arguments and or access variables from one jupyter notebook to another:

using %run with args

First issue I am having is not being able to pass arguments from one notebook to another when using the %run magic command. magic command docs. Here is the code from the notebooks:
Notebook 1:

import pandas as pd
import datetime
import mplfinance as mpf
import numpy as np
import os
from IPython.display import display, HTML
import random
import warnings
display(HTML("<style>.container { width:95% !important; }</style>"))

pd.set_option('display.width', 1000)
pd.set_option('display.max_columns', 500)
pd.set_option('display.expand_frame_repr', False)
pd.options.mode.chained_assignment = None
warnings.filterwarnings('ignore')

%run "notebook2.ipynb" 1 2

Here is the code in Notebook 2:

import pandas as pd
import datetime
import mplfinance as mpf
import numpy as np
import os
import sys
from IPython.display import display, HTML
import random
import warnings
display(HTML("<style>.container { width:95% !important; }</style>"))

pd.set_option('display.width', 1000)
pd.set_option('display.max_columns', 500)
pd.set_option('display.expand_frame_repr', False)
pd.options.mode.chained_assignment = None
warnings.filterwarnings('ignore')

print(sys.argv)

The output I get doesnt contain either variables that I am trying to pass in. Here is the output with my name redacted ['C:\\Users\\Name\\AppData\\Local\\Programs\\Python\\Python312\\Lib\\site-packages\\ipykernel_launcher.py', '-f', 'C:\\Users\\Name\\AppData\\Roaming\\jupyter\\runtime\\kernel-dc8af21c-af3f-488f-bfef-10c7b8e8f8ea.json']

Here is another stackoverflow answer I tried to follow with no luck Link

using %store

So trying this another route I decided to just store the variables / dataframes I wanted to pass in from notebook one to notebook 2. Here is an example of that with an answer on stackoverflow, And another. Yet, when I try to do it I have no luck.
Code in Notebook 1:

%store df

output of that cell Stored 'df' (DataFrame)
And in another cell

var = 1
%store var

output of that cell Stored 'var' (int)
Now on to Notebook 2:

%store -r df
%store -r var

Error Message TypeError: 'PickleShareDB' object is not subscriptable

I am not sure what the issue is, here is my current jupyter notebook setup and versioning. I have tried to restart Kernels. I am also using the same Kernel. These notebooks are in the same directory.
Current Jupyter notebook versioning:
enter image description here

Upvotes: 0

Views: 963

Answers (1)

Wayne
Wayne

Reputation: 9875

One option would be to, convert notebook2 to a Python file using Jupytext. Alternatively, read on for using %run a different way to accomplish much the same.

You can though use %run with notebooks to some extent. You've already seen that it doesn't pass args like you expect. Importantly for your plans, it turns out that by default it runs it in the same namespace as the source notebook, even without the -i flag.

Using %run: Relying on the fact the second notebook is in the same namespace to share assigned variables

For notebook1.ipynb:

import pandas as pd
import datetime
#import mplfinance as mpf
import numpy as np
import os
from IPython.display import display, HTML
import random
import warnings
display(HTML("<style>.container { width:95% !important; }</style>"))

pd.set_option('display.width', 1000)
pd.set_option('display.max_columns', 500)
pd.set_option('display.expand_frame_repr', False)
pd.options.mode.chained_assignment = None
warnings.filterwarnings('ignore')

a = 1
b = 2
%run "notebook2.ipynb" 

For notebook 2:

import pandas as pd
import datetime
#import mplfinance as mpf
import numpy as np
import os
import sys
from IPython.display import display, HTML
import random
import warnings
display(HTML("<style>.container { width:95% !important; }</style>"))

pd.set_option('display.width', 1000)
pd.set_option('display.max_columns', 500)
pd.set_option('display.expand_frame_repr', False)
pd.options.mode.chained_assignment = None
warnings.filterwarnings('ignore')

print(sys.argv)

print(a)
print(b)

(I commented out the reference to a package my environment didn't have to make your toy code, more toy.)

Using %store

Dataframes can be pickled and so that should work. You can indeed use pickled dataframes to store and read separate from using %store and so it should work. However, you provide no reproducible example or toy data and so I cannot illustrate perfectly based on what you were doing. I can guess what you meant though and try to show that...

Notebook 1:

from pandas import DataFrame
from random import choice, randint
cities = ['London', 'Delhi', 'Tokyo', 'Lagos', 'Warsaw', 'Chongqing']
df = DataFrame([
    {'salary': randint(0, 100), 'city': choice(cities)}
    for i in range(10000)
])
var = 1
%store var df 

Notebook 2:

%store -r var df 
print(var)
print(df)

Even trying other combinations more like your I couldn't get it to show what you report because this also works for Notebook 1:

from pandas import DataFrame
from random import choice, randint
cities = ['London', 'Delhi', 'Tokyo', 'Lagos', 'Warsaw', 'Chongqing']
df = DataFrame([
    {'salary': randint(0, 100), 'city': choice(cities)}
    for i in range(10000)
])
var = 1
%store df
%store var

And this also works for Notebook 2:

%store -r var 
print(var)
%store -r df 
print(df)

So without more details about your example attempt, it is hard to say why yours didn't work.

Upvotes: 1

Related Questions