Last active
January 25, 2024 19:39
-
-
Save cjerdonek/2dad48eea22846476487d594cd906493 to your computer and use it in GitHub Desktop.
Python script showing how html diffs of Jupyter notebooks can be created non-interactively (e.g. from the command-line in CI) using nbdime.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
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() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment