Coverage for src/pycse/search.py: 0.00%

59 statements  

« prev     ^ index     » next       coverage.py v7.11.0, created at 2025-10-23 16:23 -0400

1"""A Search library for Jupyter lab. 

2 

3Eventually I want to add a command you can run that opens a tab. 

4 

5it would be something like Search, it would have to take some input I assume 

6""" 

7 

8import glob 

9import ipykernel 

10import nbformat 

11import os 

12import re 

13import requests 

14from jupyter_server import serverapp as app 

15from contextlib import contextmanager 

16 

17 

18@contextmanager 

19def cwd(path): 

20 """Context manager to temporarily change working directory to PATH.""" 

21 _cwd = os.getcwd() 

22 try: 

23 os.chdir(_cwd) 

24 yield 

25 except Exception as e: 

26 raise e 

27 finally: 

28 os.chdir(_cwd) 

29 

30 

31def get_kernel_id(): 

32 """Get the current kernel id. 

33 

34 Based on the connection file. These look like: 

35 kernel-539488f9-b76d-4a55-bea9-e5f5dcaf3dc1.json 

36 and we extract out the piece like 539488f9-b76d-4a55-bea9-e5f5dcaf3dc1. 

37 """ 

38 connection_file = os.path.basename(ipykernel.get_connection_file()) 

39 fname, _ = os.path.splitext(connection_file) 

40 kernel_id = fname.replace("kernel-", "") 

41 return kernel_id 

42 

43 

44def get_server(): 

45 """Get the running server. 

46 It appears you may have many running servers. 

47 """ 

48 srvs = list(app.list_running_servers()) 

49 if len(srvs) == 1: 

50 return srvs[0] 

51 else: 

52 raise Exception("More than one running server found: {srvs}") 

53 

54 

55def get_running_notebooks(): 

56 """Get a list of all the open notebooks in the running server. 

57 It appears that each notebook runs in its own kernel. 

58 """ 

59 srv = get_server() 

60 notebooks = requests.get(srv["url"] + "api/sessions?token=" + srv["token"]).json() 

61 return notebooks 

62 

63 

64def get_notebook_path(): 

65 kernel_id = get_kernel_id() 

66 srv = get_server() 

67 notebooks = get_running_notebooks() 

68 NBS = [nb for nb in notebooks if nb["kernel"]["id"] == kernel_id] 

69 if len(NBS) == 1: 

70 nb = NBS[0] 

71 return os.path.join(srv["root_dir"], nb["notebook"]["path"]) 

72 else: 

73 raise Exception("Multiple notebooks found: {NBS}") 

74 

75 

76def get_notebook_paths(path=None, recursive=True): 

77 """Get a list of paths to all notebooks in the path. 

78 If recursive is True, find them recursively. 

79 if path is None, use the server root directory. 

80 """ 

81 if path is None: 

82 path = get_server()["root_dir"] 

83 

84 with cwd(path): 

85 nbs = glob.glob("**/*.ipynb", recursive=recursive) 

86 return nbs 

87 

88 

89def search_headings(pattern, ipynb_path): 

90 """Search for PATTERN in the headings of IPYNB_PATH. 

91 

92 Note that headings are defined as markdown lines that start with #. 

93 

94 Returns the first match. 

95 """ 

96 

97 nb = nbformat.read(ipynb_path, as_version=4) 

98 md = [cell for cell in nb["cells"] if cell["cell_type"] == "markdown"] 

99 src_lines = sum(([mc["source"].split("\n") for mc in md]), []) 

100 headings = [sl for sl in src_lines if sl.startswith("#")] 

101 

102 for heading in headings: 

103 m = re.search(pattern, heading) 

104 if m: 

105 return m 

106 

107 

108def search_markdown(pattern, ipynb_path): 

109 """Search for PATTERN in the markdown cells of IPYNB_PATH. 

110 

111 Returns the first match. 

112 """ 

113 

114 nb = nbformat.read(ipynb_path, as_version=4) 

115 md = "\n".join([cell["source"] for cell in nb["cells"] if cell["cell_type"] == "markdown"]) 

116 return re.search(pattern, md)