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
« prev ^ index » next coverage.py v7.11.0, created at 2025-10-23 16:23 -0400
1"""A Search library for Jupyter lab.
3Eventually I want to add a command you can run that opens a tab.
5it would be something like Search, it would have to take some input I assume
6"""
8import glob
9import ipykernel
10import nbformat
11import os
12import re
13import requests
14from jupyter_server import serverapp as app
15from contextlib import contextmanager
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)
31def get_kernel_id():
32 """Get the current kernel id.
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
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}")
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
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}")
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"]
84 with cwd(path):
85 nbs = glob.glob("**/*.ipynb", recursive=recursive)
86 return nbs
89def search_headings(pattern, ipynb_path):
90 """Search for PATTERN in the headings of IPYNB_PATH.
92 Note that headings are defined as markdown lines that start with #.
94 Returns the first match.
95 """
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("#")]
102 for heading in headings:
103 m = re.search(pattern, heading)
104 if m:
105 return m
108def search_markdown(pattern, ipynb_path):
109 """Search for PATTERN in the markdown cells of IPYNB_PATH.
111 Returns the first match.
112 """
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)