33import glob
44import json
55import logging
6+ from typing import Optional
67
78logging .basicConfig (level = logging .INFO )
89
910with open ("tutorials/notebook-header.md" , "r" , encoding = "utf-8" ) as header_file :
10- header_contents = header_file .read ()
11+ HEADER_CONTENTS = header_file .read ()
1112
1213
13- def find_first_cell_with_tag (cell_list , tag_to_find ):
14+ def find_first_cell_with_tag (
15+ cell_list : list , tag_to_find : str
16+ ) -> Optional [dict ]:
17+ """Returns the first cell to match a given tag given a jupyter cell dict.
18+
19+ Arguments
20+ ---------
21+ cell_list: list
22+ List of cells from a notebook as loaded from JSON
23+ tag_to_find: str
24+ The tag to look up inside of `cell["metadata"]["tags"]`
25+
26+ Returns
27+ -------
28+ dict
29+ First entry in the `cell_list` which has the matching tag as part of the
30+ metadata. If none match, then `None` is returned.
31+ """
32+
1433 for cell in cell_list :
1534 tags = cell .get ("metadata" , {}).get ("tags" , {})
1635 if tag_to_find in tags :
@@ -19,19 +38,42 @@ def find_first_cell_with_tag(cell_list, tag_to_find):
1938 return None
2039
2140
22- def update_header (header_cell , path ):
41+ def update_header_cell (header_cell : dict , tutorial_path : str ):
42+ """Updates the content of a jupyter cell from the header template.
43+
44+ Arguments
45+ ---------
46+ header_cell: dict
47+ Header cell in dict format as loaded from JSON
48+ tutorial_path: str
49+ Path to the tutorial, to substitute `{tutorialpath}` in the markdown
50+ template
51+ """
52+
2353 header_cell .update (
2454 {
2555 "cell_type" : "markdown" ,
2656 "metadata" : {"id" : "sb_auto_header" , "tags" : ["sb_auto_header" ]},
27- "source" : header_contents .replace (
28- "{tutorialpath}" , path
57+ "source" : HEADER_CONTENTS .replace (
58+ "{tutorialpath}" , tutorial_path
2959 ).splitlines (True ),
3060 }
3161 )
3262
3363
34- def update_notebook (fname ):
64+ def update_notebook (fname : str ):
65+ """Updates the tagged programmatically updated cells, see:
66+
67+ - `tutorials/notebook-header.md`
68+
69+ These cells are created when they don't exist, but they can be moved around
70+ as they are identified by their cell tag.
71+
72+ Arguments
73+ ---------
74+ fname: str
75+ Path to the notebook to update."""
76+
3577 logging .info (f"Updating { fname } " )
3678
3779 tutorial_path = fname .replace ("./" , "" )
@@ -46,7 +88,7 @@ def update_notebook(fname):
4688 cells .insert (0 , {})
4789 header_cell = cells [0 ]
4890
49- update_header (header_cell , tutorial_path )
91+ update_header_cell (header_cell , tutorial_path )
5092
5193 with open (fname , "w" ) as wf :
5294 json .dump (nb , wf , indent = 1 , ensure_ascii = False )
0 commit comments