def _create_hashable_nb( self, nb: nbf.NotebookNode, compare_nb_meta=("kernelspec", ), compare_cell_meta=None, ): """Create a notebook containing only content desired for hashing.""" nb = copy.deepcopy(nb) nb.metadata = nbf.from_dict({ k: v for k, v in nb.metadata.items() if compare_nb_meta is None or (k in compare_nb_meta) }) diff_cells = [] for cell in nb.cells: if cell.cell_type != "code": continue diff_cell = nbf.from_dict({ "cell_type": cell.cell_type, "source": cell.source, "metadata": { k: v for k, v in cell.metadata.items() if compare_cell_meta is None or (k in compare_cell_meta) }, "execution_count": None, "outputs": [], }) diff_cells.append(diff_cell) nb.cells = diff_cells return nb
def merge_match_into_notebook( self, nb: nbf.NotebookNode, nb_meta=("kernelspec", "language_info", "widgets"), cell_meta=None, ) -> Tuple[int, nbf.NotebookNode]: """Match to an executed notebook and return a merged version :param nb: The input notebook :param nb_meta: metadata keys to merge from the cached notebook (all if None) :param cell_meta: cell metadata keys to merge from cached notebook (all if None) :raises KeyError: if no match is found :return: pk, input notebook with cached code cells and metadata merged. """ pk = self.match_cache_notebook(nb).pk cache_nb = self.get_cache_bundle(pk).nb nb = copy.deepcopy(nb) if nb_meta is None: nb.metadata = cache_nb.metadata else: for key in nb_meta: if key in cache_nb.metadata: nb.metadata[key] = cache_nb.metadata[key] for idx in range(len(nb.cells)): if nb.cells[idx].cell_type == "code": cache_cell = cache_nb.cells.pop(0) if cell_meta is not None: # update the input metadata with select cached notebook metadata # then add the input metadata to the cached cell nb.cells[idx].metadata.update( {k: v for k, v in cache_cell.metadata.items() if k in cell_meta} ) cache_cell.metadata = nb.cells[idx].metadata nb.cells[idx] = cache_cell return pk, nb