Recently I wrote a post on how a simple method to pass arguments from a parent python script to a Jupyter notebook, so that we can automate the generation of different reports based on a same notebook.

I just figured out a more elegant way, which is to simply use a JSON file.

Let’s say we have a Jupyter notebook that plots the contents of a csv file:

import pandas as pd
import matplotlib.pyplot as plt

data = pd.read_csv(filename)
plt.plot(data)

and we want to run this notebook on different csv files. We could write a parent script that will save arguments as a JSON file, and modify the notebook to read this JSON file.

Parent script

import json
import subprocess

def run_notebook(notebook_file, output_file, **arguments):
    """Pass arguments to a Jupyter notebook, run it and convert to html."""
    # Create the arguments file
    with open('arguments.json', 'w') as fid:
        json.dump(arguments, fid)
    # Run the notebook
    subprocess.call([
        'jupyter-nbconvert',
        '--execute',
        '--to', 'html',
        '--output', output_file,
        notebook_file])

# Run the notebook with different arguments
run_notebook('the_notebook.ipynb', 'report1.html', filename='data1.csv')
run_notebook('the_notebook.ipynb', 'report2.html', filename='data2.csv')
run_notebook('the_notebook.ipynb', 'report3.html', filename='data3.csv')

Child notebook (the_notebook.ipynb)

import json
import pandas as pd
import matplotlib.pyplot as plt

# Load the arguments
with open('arguments.json', 'r') as fid:
    arguments = json.load(fid)

# Do the work
data = pd.read_csv(arguments['filename'])
plt.plot(data)