Skill Tracer
Skills › Scientific Agent Skills › open-notebook › notebook_management.py

notebook_management.py

72 lines · skills/open-notebook/scripts/notebook_management.py at 5f2bc03

1"""Notebook helpers using requests; running this file lists notebooks only.
2
3Usage: uv run --isolated --with requests python notebook_management.py --help
4Set OPEN_NOTEBOOK_URL to the backend origin and OPEN_NOTEBOOK_PASSWORD if enabled.
5"""
6
7import argparse
8import json
9
10from _common import record_path, request_json
13def create_notebook(name, description=""):
14 return request_json("POST", "/notebooks", json={
15 "name": name, "description": description,
16 })
19def list_notebooks(archived=None):
20 """Return all notebooks; a supplied bool filters active/archived notebooks."""
21 params = {} if archived is None else {"archived": str(archived).lower()}
22 return request_json("GET", "/notebooks", params=params)
25def get_notebook(notebook_id):
26 return request_json("GET", f"/notebooks/{record_path(notebook_id)}")
29def update_notebook(notebook_id, name=None, description=None, archived=None):
30 payload = {key: value for key, value in {
31 "name": name, "description": description, "archived": archived,
32 }.items() if value is not None}
33 return request_json("PUT", f"/notebooks/{record_path(notebook_id)}", json=payload)
36def delete_notebook(notebook_id, delete_sources=False):
37 """Delete notebook, its notes/chats, and optionally its exclusive sources.
39 The Python argument is retained for compatibility; the API query parameter is
40 delete_exclusive_sources. Inspect the returned counts, not a guessed count.
41 """
42 path = f"/notebooks/{record_path(notebook_id)}"
43 preview = request_json("GET", path + "/delete-preview")
44 print(f"Deleting {preview['note_count']} notes; "
45 f"{preview['exclusive_source_count']} exclusive and "
46 f"{preview['shared_source_count']} shared sources affected")
47 return request_json("DELETE", path, params={
48 "delete_exclusive_sources": str(delete_sources).lower(),
49 })
52def link_source_to_notebook(notebook_id, source_id):
53 """Associate a source; verify membership before repeatedly linking it."""
54 return request_json("POST", f"/notebooks/{record_path(notebook_id)}"
55 f"/sources/{record_path(source_id)}")
58def unlink_source_from_notebook(notebook_id, source_id):
59 return request_json("DELETE", f"/notebooks/{record_path(notebook_id)}"
60 f"/sources/{record_path(source_id)}")
63def main():
64 parser = argparse.ArgumentParser(description=__doc__)
65 parser.add_argument("--archived", choices=["true", "false"])
66 args = parser.parse_args()
67 archived = None if args.archived is None else args.archived == "true"
68 print(json.dumps(list_notebooks(archived), indent=2))
71if __name__ == "__main__":
72 main()