""" Python script showing how html diffs of Jupyter notebooks can be created non-interactively (e.g. from the command-line in CI) using nbdime (https://github.com/jupyter/nbdime) in combination with nbdime PR #744: https://github.com/jupyter/nbdime/pull/744 Usage: $ python test-nbdime-html-diff.py NB_PATH1 NB_PATH2 """ from pathlib import Path import sys import jinja2 from jinja2 import Environment, FileSystemLoader import nbdime.diffing.notebooks as notebooks import nbdime.utils as nb_utils import nbdime.webapp as webapp WEBAPP_DIR = Path(webapp.__file__).parent def read_notebook(path): with path.open() as f: data = nb_utils.read_notebook(f, on_null='empty') return data def diff_notebooks(path1, path2, output_path, static_dir): nb_data1 = read_notebook(path1) nb_data2 = read_notebook(path2) # Here is where you can tell nbdime what to include and ignore. # For example, tell nbdime to ignore differences in cell metadata. notebooks.set_notebook_diff_targets(metadata=False) diff_result = notebooks.diff_notebooks(nb_data1, nb_data2) template_dir = WEBAPP_DIR / 'templates' template_loader = FileSystemLoader(template_dir) env = Environment( loader=template_loader, autoescape=jinja2.select_autoescape(), ) template = env.get_template('diff.html') def static_url(rel_path): path = static_dir / rel_path return path # The showDiff() function in the nbdime package's diff.ts file # expects key-values "base" and "diff". diff_data = { 'base': nb_data1, 'diff': diff_result, } config_data = { 'base': str(path1), 'remote': str(path2), 'diff_data': diff_data, } context = { # The nbdime package's base nbdimepage.html template calls tojson() # on the config_data value. 'config_data': config_data, 'static_url': static_url, } html = template.render(context) output_path.write_text(html) def main(): args = sys.argv[1:] assert len(args) == 2 path1, path2 = (Path(path) for path in args) output_path = Path('test-diff.html') # Pass a static_dir that lets us test the locally generated JS. static_dir = WEBAPP_DIR.absolute() / 'static' diff_notebooks( path1, path2=path2, output_path=output_path, static_dir=static_dir, ) print(f'wrote output to: {output_path}') if __name__ == '__main__': main()