Passing command line arguments to argv in jupyter/ipython notebook
Question:
I’m wondering if it’s possible to populate sys.argv
(or some other structure) with command line arguments in a jupyter/ipython notebook, similar to how it’s done through a python script.
For instance, if I were to run a python script as follows:
python test.py False
Then sys.argv
would contain the argument False
. But if I run a jupyter notebook in a similar manner:
jupyter notebook test.ipynb False
Then the command line argument gets lost. Is there any way to access this argument from within the notebook itself?
Answers:
I think this Gist may help you : https://gist.github.com/gbishop/acf40b86a9bca2d571fa
This is an attempt at a simple argument parser for mostly key=value pairs that can be used both on the command line and in IPython notebooks. It support query parameters in notebook URLs and a Run command for notebooks.
After a lot of looking around I found very cumbersome, custom libraries, but solved it with a few lines of code which I thought was pretty slick. I used nbconvert to end up with an html report as output that contains all graphics and markdown from the notebook, but accepts command line parameters just as always through a minimal python wrapper:
The python file test_args.py (which takes command line params as normal):
import sys,os
IPYNB_FILENAME = 'test_argv.ipynb'
CONFIG_FILENAME = '.config_ipynb'
def main(argv):
with open(CONFIG_FILENAME,'w') as f:
f.write(' '.join(argv))
os.system('jupyter nbconvert --execute {:s} --to html'.format(IPYNB_FILENAME))
return None
if __name__ == '__main__':
main(sys.argv)
The notebook contains:
import sys,os,argparse
from IPython.display import HTML
CONFIG_FILE = '.config_ipynb'
if os.path.isfile(CONFIG_FILE):
with open(CONFIG_FILE) as f:
sys.argv = f.read().split()
else:
sys.argv = ['test_args.py', 'input_file', '--int_param', '12']
parser = argparse.ArgumentParser()
parser.add_argument("input_file",help="Input image, directory, or npy.")
parser.add_argument("--int_param", type=int, default=4, help="an optional integer parameter.")
args = parser.parse_args()
p = args.int_param
print(args.input_file,p)
and I can run the python notebook with arguments parsed as usual:
python test_args.py my_input_file --int_param 12
I tend to paste the block with argparse calls into the python wrapper so that command line errors are caught by the python script and -h works properly.
Using args = parser.parse_args(args=[])
would work.
or for testing, you can declare it as class format.
class Args:
data = './data/penn'
model = 'LSTM'
emsize = 200
nhid = 200
args=Args()
There are two projects I’ve found that do what you ask for
- Papermill, will add a cell to your notebook with arguments that you pass to it on the command line. So this is quite straightforward, you define your defaults in the first cell (the should have
parameters
tag)
- nbparameterise it is a similar concept but you don’t tag your cell with defaults, it has to be first.
Here is a good resource discussing the issue: https://github.com/jupyter/help/issues/218
sys.argv
yields a list
, so I used
sys.argv.append('hello')
in a jupyter notebook, which allowed me to append extra members and pretend like I’m passing in arguments from the command line.
A workaround is to make the jupyter notebook read the arguments from a file.
From the command line, modify the file and run the notebook.
If the goal is to run a notebook with configurable arguments passed from commandline, I think the easiest way is to use environment variables, like this:
NB_ARGS=some_args jupyter nbconvert --execute --to html --template full some_notebook.ipynb
Then in the notebook, you can import os
and use os.environ['NB_ARGS']
. The variable value can be some text that contains key-value pairs or json for example.
I assume that you just want to parse some arguments to the notebooks, but it’s not necessary to use the command line.
If you want to parse commands like.
python script.py --a A --b B
You can use the following code in the notebook:
cmd = '--a A --b B'
args = args = parser.parse_args(cmd)
For parse_args
, you can find more information here.
At the top of the Jupyter cell, put a line like:
%%python - --option1 value1 --option2 value2 --etc
In your example:
%%python - True
This will run your script like in a command line with the args provided.
Example:
%%python - --option1 value1 --option2 value2 --etc
import sys
if __name__ == '__main__':
print(sys.argv)
will output:
['-', '--option1', 'value1', '--option2', 'value2', '--etc']
Hope it helps.
A simple and naïve solution is to put the following snippet at the first line of your program:
import sys
sys.argv = "your expected command line arguments here".split()
After executing this command, packages like argparse
will work well.
So, you can just run your scripts in the jupyter lab server, without opening a terminal and typing your arguments.
I tried out the answers listed above, and came up with a different solution.
My original code was
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", required=True, help="path to input image")
ap.add_argument("-y", "--yolo", required=True, help="base path to YOLO directory")
ap.add_argument("-c", "--confidence", type=float, default=0.5, help="minimum probability to filter weak detections")
ap.add_argument("-t", "--threshold", type=float, default=0.3, help="threshold when applying non-maxima suppression")
args = vars(ap.parse_args())
I tried to make a Class as
Class Args():
image='photo.jpg'
yolo='yolo-coco'
confidence=0.5
threshold=0.3
args=Args()
but futher code snippets were producing an error.
So I printed args
after vars(ap.parse_args())
and found that it was a dictionary.
So just create a dictionary for the original args:
args={"image": 'photo.jpg', "yolo": 'yolo-coco', "confidence": 0.5,"threshold": 0.3}
I’m wondering if it’s possible to populate sys.argv
(or some other structure) with command line arguments in a jupyter/ipython notebook, similar to how it’s done through a python script.
For instance, if I were to run a python script as follows:
python test.py False
Then sys.argv
would contain the argument False
. But if I run a jupyter notebook in a similar manner:
jupyter notebook test.ipynb False
Then the command line argument gets lost. Is there any way to access this argument from within the notebook itself?
I think this Gist may help you : https://gist.github.com/gbishop/acf40b86a9bca2d571fa
This is an attempt at a simple argument parser for mostly key=value pairs that can be used both on the command line and in IPython notebooks. It support query parameters in notebook URLs and a Run command for notebooks.
After a lot of looking around I found very cumbersome, custom libraries, but solved it with a few lines of code which I thought was pretty slick. I used nbconvert to end up with an html report as output that contains all graphics and markdown from the notebook, but accepts command line parameters just as always through a minimal python wrapper:
The python file test_args.py (which takes command line params as normal):
import sys,os
IPYNB_FILENAME = 'test_argv.ipynb'
CONFIG_FILENAME = '.config_ipynb'
def main(argv):
with open(CONFIG_FILENAME,'w') as f:
f.write(' '.join(argv))
os.system('jupyter nbconvert --execute {:s} --to html'.format(IPYNB_FILENAME))
return None
if __name__ == '__main__':
main(sys.argv)
The notebook contains:
import sys,os,argparse
from IPython.display import HTML
CONFIG_FILE = '.config_ipynb'
if os.path.isfile(CONFIG_FILE):
with open(CONFIG_FILE) as f:
sys.argv = f.read().split()
else:
sys.argv = ['test_args.py', 'input_file', '--int_param', '12']
parser = argparse.ArgumentParser()
parser.add_argument("input_file",help="Input image, directory, or npy.")
parser.add_argument("--int_param", type=int, default=4, help="an optional integer parameter.")
args = parser.parse_args()
p = args.int_param
print(args.input_file,p)
and I can run the python notebook with arguments parsed as usual:
python test_args.py my_input_file --int_param 12
I tend to paste the block with argparse calls into the python wrapper so that command line errors are caught by the python script and -h works properly.
Using args = parser.parse_args(args=[])
would work.
or for testing, you can declare it as class format.
class Args:
data = './data/penn'
model = 'LSTM'
emsize = 200
nhid = 200
args=Args()
There are two projects I’ve found that do what you ask for
- Papermill, will add a cell to your notebook with arguments that you pass to it on the command line. So this is quite straightforward, you define your defaults in the first cell (the should have
parameters
tag) - nbparameterise it is a similar concept but you don’t tag your cell with defaults, it has to be first.
Here is a good resource discussing the issue: https://github.com/jupyter/help/issues/218
sys.argv
yields a list
, so I used
sys.argv.append('hello')
in a jupyter notebook, which allowed me to append extra members and pretend like I’m passing in arguments from the command line.
A workaround is to make the jupyter notebook read the arguments from a file.
From the command line, modify the file and run the notebook.
If the goal is to run a notebook with configurable arguments passed from commandline, I think the easiest way is to use environment variables, like this:
NB_ARGS=some_args jupyter nbconvert --execute --to html --template full some_notebook.ipynb
Then in the notebook, you can import os
and use os.environ['NB_ARGS']
. The variable value can be some text that contains key-value pairs or json for example.
I assume that you just want to parse some arguments to the notebooks, but it’s not necessary to use the command line.
If you want to parse commands like.
python script.py --a A --b B
You can use the following code in the notebook:
cmd = '--a A --b B'
args = args = parser.parse_args(cmd)
For parse_args
, you can find more information here.
At the top of the Jupyter cell, put a line like:
%%python - --option1 value1 --option2 value2 --etc
In your example:
%%python - True
This will run your script like in a command line with the args provided.
Example:
%%python - --option1 value1 --option2 value2 --etc
import sys
if __name__ == '__main__':
print(sys.argv)
will output:
['-', '--option1', 'value1', '--option2', 'value2', '--etc']
Hope it helps.
A simple and naïve solution is to put the following snippet at the first line of your program:
import sys
sys.argv = "your expected command line arguments here".split()
After executing this command, packages like argparse
will work well.
So, you can just run your scripts in the jupyter lab server, without opening a terminal and typing your arguments.
I tried out the answers listed above, and came up with a different solution.
My original code was
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", required=True, help="path to input image")
ap.add_argument("-y", "--yolo", required=True, help="base path to YOLO directory")
ap.add_argument("-c", "--confidence", type=float, default=0.5, help="minimum probability to filter weak detections")
ap.add_argument("-t", "--threshold", type=float, default=0.3, help="threshold when applying non-maxima suppression")
args = vars(ap.parse_args())
I tried to make a Class as
Class Args():
image='photo.jpg'
yolo='yolo-coco'
confidence=0.5
threshold=0.3
args=Args()
but futher code snippets were producing an error.
So I printed args
after vars(ap.parse_args())
and found that it was a dictionary.
So just create a dictionary for the original args:
args={"image": 'photo.jpg', "yolo": 'yolo-coco', "confidence": 0.5,"threshold": 0.3}