notebooklm-py 0.1.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. notebooklm_py-0.1.1/.claude/settings.local.json +18 -0
  2. notebooklm_py-0.1.1/.env.example +35 -0
  3. notebooklm_py-0.1.1/.github/workflows/nightly.yml +64 -0
  4. notebooklm_py-0.1.1/.github/workflows/publish.yml +34 -0
  5. notebooklm_py-0.1.1/.github/workflows/test.yml +80 -0
  6. notebooklm_py-0.1.1/.gitignore +19 -0
  7. notebooklm_py-0.1.1/AGENTS.md +115 -0
  8. notebooklm_py-0.1.1/CHANGELOG.md +65 -0
  9. notebooklm_py-0.1.1/CLAUDE.md +168 -0
  10. notebooklm_py-0.1.1/CONTRIBUTING.md +124 -0
  11. notebooklm_py-0.1.1/LICENSE +21 -0
  12. notebooklm_py-0.1.1/PKG-INFO +208 -0
  13. notebooklm_py-0.1.1/README.md +162 -0
  14. notebooklm_py-0.1.1/RELEASING.md +50 -0
  15. notebooklm_py-0.1.1/SECURITY.md +106 -0
  16. notebooklm_py-0.1.1/docs/README.md +35 -0
  17. notebooklm_py-0.1.1/docs/cli-reference.md +537 -0
  18. notebooklm_py-0.1.1/docs/configuration.md +389 -0
  19. notebooklm_py-0.1.1/docs/contributing/adding-rpc-methods.md +379 -0
  20. notebooklm_py-0.1.1/docs/contributing/architecture.md +249 -0
  21. notebooklm_py-0.1.1/docs/contributing/debugging.md +325 -0
  22. notebooklm_py-0.1.1/docs/contributing/testing.md +558 -0
  23. notebooklm_py-0.1.1/docs/designs/notebooklm-skill.md +137 -0
  24. notebooklm_py-0.1.1/docs/examples/bulk-import.py +110 -0
  25. notebooklm_py-0.1.1/docs/examples/quickstart.py +78 -0
  26. notebooklm_py-0.1.1/docs/examples/research-to-podcast.py +95 -0
  27. notebooklm_py-0.1.1/docs/getting-started.md +180 -0
  28. notebooklm_py-0.1.1/docs/python-api.md +783 -0
  29. notebooklm_py-0.1.1/docs/reference/internals/rpc-capture.md +380 -0
  30. notebooklm_py-0.1.1/docs/reference/internals/rpc-ui-reference.md +1290 -0
  31. notebooklm_py-0.1.1/docs/releasing.md +130 -0
  32. notebooklm_py-0.1.1/docs/stability.md +168 -0
  33. notebooklm_py-0.1.1/docs/troubleshooting.md +395 -0
  34. notebooklm_py-0.1.1/examples/chat_and_ask.py +185 -0
  35. notebooklm_py-0.1.1/examples/file_upload_example.py +53 -0
  36. notebooklm_py-0.1.1/examples/notes_and_mind_maps.py +256 -0
  37. notebooklm_py-0.1.1/examples/podcast_generation.py +102 -0
  38. notebooklm_py-0.1.1/examples/research_workflow.py +158 -0
  39. notebooklm_py-0.1.1/examples/video_generation.py +157 -0
  40. notebooklm_py-0.1.1/notebooklm-py.png +0 -0
  41. notebooklm_py-0.1.1/pyproject.toml +90 -0
  42. notebooklm_py-0.1.1/scripts/heal_golden_notebook.py +252 -0
  43. notebooklm_py-0.1.1/scripts/pre_release_check.sh +49 -0
  44. notebooklm_py-0.1.1/src/notebooklm/__init__.py +108 -0
  45. notebooklm_py-0.1.1/src/notebooklm/_artifacts.py +1460 -0
  46. notebooklm_py-0.1.1/src/notebooklm/_chat.py +386 -0
  47. notebooklm_py-0.1.1/src/notebooklm/_core.py +252 -0
  48. notebooklm_py-0.1.1/src/notebooklm/_notebooks.py +273 -0
  49. notebooklm_py-0.1.1/src/notebooklm/_notes.py +308 -0
  50. notebooklm_py-0.1.1/src/notebooklm/_research.py +256 -0
  51. notebooklm_py-0.1.1/src/notebooklm/_sources.py +752 -0
  52. notebooklm_py-0.1.1/src/notebooklm/auth.py +427 -0
  53. notebooklm_py-0.1.1/src/notebooklm/cli/__init__.py +136 -0
  54. notebooklm_py-0.1.1/src/notebooklm/cli/artifact.py +472 -0
  55. notebooklm_py-0.1.1/src/notebooklm/cli/chat.py +246 -0
  56. notebooklm_py-0.1.1/src/notebooklm/cli/download.py +720 -0
  57. notebooklm_py-0.1.1/src/notebooklm/cli/download_helpers.py +135 -0
  58. notebooklm_py-0.1.1/src/notebooklm/cli/generate.py +702 -0
  59. notebooklm_py-0.1.1/src/notebooklm/cli/grouped.py +75 -0
  60. notebooklm_py-0.1.1/src/notebooklm/cli/helpers.py +494 -0
  61. notebooklm_py-0.1.1/src/notebooklm/cli/note.py +222 -0
  62. notebooklm_py-0.1.1/src/notebooklm/cli/notebook.py +247 -0
  63. notebooklm_py-0.1.1/src/notebooklm/cli/options.py +93 -0
  64. notebooklm_py-0.1.1/src/notebooklm/cli/research.py +215 -0
  65. notebooklm_py-0.1.1/src/notebooklm/cli/session.py +302 -0
  66. notebooklm_py-0.1.1/src/notebooklm/cli/skill.py +153 -0
  67. notebooklm_py-0.1.1/src/notebooklm/cli/source.py +708 -0
  68. notebooklm_py-0.1.1/src/notebooklm/client.py +175 -0
  69. notebooklm_py-0.1.1/src/notebooklm/data/SKILL.md +378 -0
  70. notebooklm_py-0.1.1/src/notebooklm/notebooklm_cli.py +112 -0
  71. notebooklm_py-0.1.1/src/notebooklm/paths.py +105 -0
  72. notebooklm_py-0.1.1/src/notebooklm/rpc/__init__.py +66 -0
  73. notebooklm_py-0.1.1/src/notebooklm/rpc/decoder.py +250 -0
  74. notebooklm_py-0.1.1/src/notebooklm/rpc/encoder.py +98 -0
  75. notebooklm_py-0.1.1/src/notebooklm/rpc/types.py +273 -0
  76. notebooklm_py-0.1.1/src/notebooklm/types.py +636 -0
  77. notebooklm_py-0.1.1/tests/conftest.py +86 -0
  78. notebooklm_py-0.1.1/tests/e2e/__init__.py +0 -0
  79. notebooklm_py-0.1.1/tests/e2e/conftest.py +436 -0
  80. notebooklm_py-0.1.1/tests/e2e/test_artifacts.py +238 -0
  81. notebooklm_py-0.1.1/tests/e2e/test_downloads.py +135 -0
  82. notebooklm_py-0.1.1/tests/e2e/test_file_upload.py +100 -0
  83. notebooklm_py-0.1.1/tests/e2e/test_generation.py +416 -0
  84. notebooklm_py-0.1.1/tests/e2e/test_notebooks.py +138 -0
  85. notebooklm_py-0.1.1/tests/e2e/test_notes.py +106 -0
  86. notebooklm_py-0.1.1/tests/e2e/test_research.py +258 -0
  87. notebooklm_py-0.1.1/tests/e2e/test_sources.py +252 -0
  88. notebooklm_py-0.1.1/tests/integration/conftest.py +74 -0
  89. notebooklm_py-0.1.1/tests/integration/test_artifacts.py +791 -0
  90. notebooklm_py-0.1.1/tests/integration/test_chat.py +158 -0
  91. notebooklm_py-0.1.1/tests/integration/test_core.py +25 -0
  92. notebooklm_py-0.1.1/tests/integration/test_download_multi_artifact.py +295 -0
  93. notebooklm_py-0.1.1/tests/integration/test_notebooks.py +482 -0
  94. notebooklm_py-0.1.1/tests/integration/test_notes.py +235 -0
  95. notebooklm_py-0.1.1/tests/integration/test_research_api.py +252 -0
  96. notebooklm_py-0.1.1/tests/integration/test_sources.py +544 -0
  97. notebooklm_py-0.1.1/tests/unit/cli/__init__.py +1 -0
  98. notebooklm_py-0.1.1/tests/unit/cli/conftest.py +165 -0
  99. notebooklm_py-0.1.1/tests/unit/cli/test_artifact.py +594 -0
  100. notebooklm_py-0.1.1/tests/unit/cli/test_download.py +357 -0
  101. notebooklm_py-0.1.1/tests/unit/cli/test_generate.py +427 -0
  102. notebooklm_py-0.1.1/tests/unit/cli/test_grouped.py +122 -0
  103. notebooklm_py-0.1.1/tests/unit/cli/test_helpers.py +544 -0
  104. notebooklm_py-0.1.1/tests/unit/cli/test_note.py +296 -0
  105. notebooklm_py-0.1.1/tests/unit/cli/test_notebook.py +623 -0
  106. notebooklm_py-0.1.1/tests/unit/cli/test_resolve.py +330 -0
  107. notebooklm_py-0.1.1/tests/unit/cli/test_session.py +358 -0
  108. notebooklm_py-0.1.1/tests/unit/cli/test_skill.py +154 -0
  109. notebooklm_py-0.1.1/tests/unit/cli/test_source.py +627 -0
  110. notebooklm_py-0.1.1/tests/unit/test_api_coverage.py +305 -0
  111. notebooklm_py-0.1.1/tests/unit/test_artifact_downloads.py +370 -0
  112. notebooklm_py-0.1.1/tests/unit/test_auth.py +670 -0
  113. notebooklm_py-0.1.1/tests/unit/test_client.py +309 -0
  114. notebooklm_py-0.1.1/tests/unit/test_conversation.py +96 -0
  115. notebooklm_py-0.1.1/tests/unit/test_decoder.py +411 -0
  116. notebooklm_py-0.1.1/tests/unit/test_download_helpers.py +188 -0
  117. notebooklm_py-0.1.1/tests/unit/test_encoder.py +201 -0
  118. notebooklm_py-0.1.1/tests/unit/test_notes_unit.py +637 -0
  119. notebooklm_py-0.1.1/tests/unit/test_paths.py +128 -0
  120. notebooklm_py-0.1.1/tests/unit/test_research.py +90 -0
  121. notebooklm_py-0.1.1/tests/unit/test_rpc_types.py +90 -0
  122. notebooklm_py-0.1.1/tests/unit/test_source_status.py +258 -0
  123. notebooklm_py-0.1.1/tests/unit/test_sources_upload.py +512 -0
  124. notebooklm_py-0.1.1/tests/unit/test_types.py +444 -0
  125. notebooklm_py-0.1.1/tests/unit/test_youtube_extraction.py +68 -0
@@ -0,0 +1,18 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(pytest:*)",
5
+ "Bash(pip install:*)",
6
+ "Bash(python3 -m pip:*)",
7
+ "Bash(uv pip install:*)",
8
+ "Bash(grep:*)",
9
+ "Bash(tree:*)",
10
+ "Bash(python -m pytest:*)",
11
+ "Bash(python3:*)",
12
+ "Bash(source:*)",
13
+ "WebFetch(domain:github.com)",
14
+ "WebFetch(domain:raw.githubusercontent.com)",
15
+ "Bash(curl:*)"
16
+ ]
17
+ }
18
+ }
@@ -0,0 +1,35 @@
1
+ # NotebookLM Configuration
2
+ # Copy this file to .env and fill in your values
3
+
4
+ # =============================================================================
5
+ # Configuration Environment Variables
6
+ # =============================================================================
7
+
8
+ # Custom home directory for all config files (optional)
9
+ # Default: ~/.notebooklm
10
+ # NOTEBOOKLM_HOME=/custom/path
11
+
12
+ # Inline authentication JSON for CI/CD (optional)
13
+ # When set, authentication is read from this variable instead of a file
14
+ # Get the value from: cat $NOTEBOOKLM_HOME/storage_state.json (default: ~/.notebooklm)
15
+ # NOTEBOOKLM_AUTH_JSON='{"cookies":[...]}'
16
+
17
+ # Enable RPC debug logging (optional)
18
+ # NOTEBOOKLM_DEBUG_RPC=1
19
+
20
+ # =============================================================================
21
+ # E2E Testing Configuration
22
+ # =============================================================================
23
+
24
+ # Required for E2E tests: Your READ-ONLY test notebook ID
25
+ # Create a notebook at https://notebooklm.google.com with:
26
+ # - Multiple sources (text, URL, PDF, etc.)
27
+ # - Some pre-generated artifacts (audio, quiz, etc.)
28
+ # Copy the notebook ID from the URL: notebooklm.google.com/notebook/YOUR_ID
29
+ # This notebook is used for READ-ONLY tests (list, get, download operations)
30
+ NOTEBOOKLM_READ_ONLY_NOTEBOOK_ID=your-notebook-id-here
31
+
32
+ # Optional: Generation test notebook ID
33
+ # If not set, a notebook will be auto-created and its ID stored in
34
+ # NOTEBOOKLM_HOME/generation_notebook_id for reuse across test runs.
35
+ # NOTEBOOKLM_GENERATION_NOTEBOOK_ID=your-generation-notebook-id
@@ -0,0 +1,64 @@
1
+ name: Nightly E2E Tests
2
+
3
+ on:
4
+ schedule:
5
+ # Run at 6 AM UTC daily (10 PM PST / 1 AM EST)
6
+ - cron: '0 6 * * *'
7
+ workflow_dispatch: # Allow manual trigger
8
+
9
+ concurrency:
10
+ group: ${{ github.workflow }}
11
+ cancel-in-progress: true
12
+
13
+ jobs:
14
+ e2e:
15
+ name: E2E Tests
16
+ runs-on: ubuntu-latest
17
+ # Only run on main repo (not forks) due to secrets requirement
18
+ if: github.repository == 'teng-lin/notebooklm-py'
19
+
20
+ steps:
21
+ - uses: actions/checkout@v4
22
+
23
+ - name: Set up Python
24
+ uses: actions/setup-python@v5
25
+ with:
26
+ python-version: "3.12"
27
+ cache: 'pip'
28
+
29
+ - name: Install dependencies
30
+ run: |
31
+ python -m pip install --upgrade pip
32
+ pip install -e ".[all]"
33
+
34
+ - name: Get Playwright version
35
+ id: playwright-version
36
+ run: |
37
+ echo "version=$(pip show playwright | grep Version | cut -d' ' -f2)" >> $GITHUB_OUTPUT
38
+
39
+ - name: Cache Playwright browsers
40
+ uses: actions/cache@v4
41
+ with:
42
+ path: ~/.cache/ms-playwright
43
+ key: playwright-ubuntu-latest-${{ steps.playwright-version.outputs.version }}
44
+
45
+ - name: Install Playwright browsers and dependencies
46
+ run: |
47
+ playwright install chromium
48
+ playwright install-deps
49
+
50
+ - name: Set up authentication
51
+ env:
52
+ NOTEBOOKLM_STORAGE_STATE: ${{ secrets.NOTEBOOKLM_STORAGE_STATE }}
53
+ run: |
54
+ mkdir -p ~/.notebooklm
55
+ echo "$NOTEBOOKLM_STORAGE_STATE" > ~/.notebooklm/storage_state.json
56
+
57
+ - name: Run E2E tests
58
+ env:
59
+ NOTEBOOKLM_READ_ONLY_NOTEBOOK_ID: ${{ secrets.NOTEBOOKLM_READ_ONLY_NOTEBOOK_ID }}
60
+ run: pytest tests/e2e -m e2e -v --tb=short
61
+
62
+ - name: Clean up authentication
63
+ if: always()
64
+ run: rm -rf ~/.notebooklm
@@ -0,0 +1,34 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*"
7
+
8
+ jobs:
9
+ build-and-publish:
10
+ name: Build and publish to PyPI
11
+ runs-on: ubuntu-latest
12
+ permissions:
13
+ id-token: write
14
+ contents: read
15
+
16
+ steps:
17
+ - uses: actions/checkout@v4
18
+
19
+ - name: Set up Python 3.12
20
+ uses: actions/setup-python@v5
21
+ with:
22
+ python-version: "3.12"
23
+
24
+ - name: Install build tools
25
+ run: |
26
+ python -m pip install --upgrade pip
27
+ pip install build
28
+
29
+ - name: Build package
30
+ run: |
31
+ python -m build
32
+
33
+ - name: Publish to PyPI
34
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,80 @@
1
+ name: Test
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ concurrency:
10
+ group: ${{ github.workflow }}-${{ github.ref }}
11
+ cancel-in-progress: true
12
+
13
+ jobs:
14
+ quality:
15
+ name: Code Quality
16
+ runs-on: ubuntu-latest
17
+ steps:
18
+ - uses: actions/checkout@v4
19
+
20
+ - name: Set up Python
21
+ uses: actions/setup-python@v5
22
+ with:
23
+ python-version: "3.12"
24
+ cache: 'pip'
25
+
26
+ - name: Install dependencies
27
+ run: |
28
+ python -m pip install --upgrade pip
29
+ pip install -e ".[all]"
30
+
31
+ - name: Run linting
32
+ run: ruff check src/
33
+
34
+ - name: Run type checking
35
+ run: mypy src/notebooklm --ignore-missing-imports
36
+
37
+ test:
38
+ name: Test (${{ matrix.os }}, Python ${{ matrix.python-version }})
39
+ runs-on: ${{ matrix.os }}
40
+ needs: quality
41
+ strategy:
42
+ fail-fast: false
43
+ matrix:
44
+ os: [ubuntu-latest, macos-latest]
45
+ python-version: ["3.9", "3.10", "3.11", "3.12"]
46
+
47
+ steps:
48
+ - uses: actions/checkout@v4
49
+
50
+ - name: Set up Python ${{ matrix.python-version }}
51
+ uses: actions/setup-python@v5
52
+ with:
53
+ python-version: ${{ matrix.python-version }}
54
+ cache: 'pip'
55
+
56
+ - name: Install dependencies
57
+ run: |
58
+ python -m pip install --upgrade pip
59
+ pip install -e ".[all]"
60
+
61
+ - name: Get Playwright version
62
+ id: playwright-version
63
+ run: |
64
+ echo "version=$(pip show playwright | grep Version | cut -d' ' -f2)" >> $GITHUB_OUTPUT
65
+
66
+ - name: Cache Playwright browsers
67
+ uses: actions/cache@v4
68
+ with:
69
+ path: ~/.cache/ms-playwright
70
+ key: playwright-${{ matrix.os }}-${{ steps.playwright-version.outputs.version }}
71
+
72
+ - name: Install Playwright browsers
73
+ run: playwright install chromium
74
+
75
+ - name: Install Playwright system dependencies (Linux)
76
+ if: runner.os == 'Linux'
77
+ run: playwright install-deps
78
+
79
+ - name: Run tests with coverage
80
+ run: pytest --cov=src/notebooklm --cov-report=term-missing --cov-fail-under=70
@@ -0,0 +1,19 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ *.class
4
+ .venv/
5
+ env/
6
+ venv/
7
+ .pytest_cache/
8
+ .coverage
9
+ htmlcov/
10
+ dist/
11
+ build/
12
+ *.egg-info/
13
+ .DS_Store
14
+ .env
15
+ .notebooklm/
16
+ captured_rpcs/
17
+ .worktrees/
18
+ .worktree/
19
+ .sisyphus/
@@ -0,0 +1,115 @@
1
+ # AGENTS.md
2
+
3
+ Guidelines for AI agents working on `notebooklm-py`.
4
+
5
+ **IMPORTANT:** Follow documentation rules in [CONTRIBUTING.md](CONTRIBUTING.md) - especially the file creation and naming conventions.
6
+
7
+ ## Quick Reference
8
+
9
+ See [CLAUDE.md](CLAUDE.md) for full project context. Essential commands:
10
+
11
+ ```bash
12
+ source .venv/bin/activate # Always activate venv first
13
+ pytest # Run tests
14
+ pip install -e ".[all]" # Install in dev mode
15
+ ```
16
+
17
+ ## Code Style Guidelines
18
+
19
+ ### Type Annotations (Python 3.9+)
20
+ ```python
21
+ def process(items: list[str]) -> dict[str, Any]: ...
22
+ async def query(notebook_id: str, source_ids: Optional[list[str]] = None): ...
23
+
24
+ # Use TYPE_CHECKING for circular imports
25
+ from typing import TYPE_CHECKING
26
+ if TYPE_CHECKING:
27
+ from ..api_client import NotebookLMClient
28
+ ```
29
+
30
+ ### Async Patterns
31
+ ```python
32
+ # All client methods are async - use namespaced APIs
33
+ async with await NotebookLMClient.from_storage() as client:
34
+ notebooks = await client.notebooks.list()
35
+ await client.sources.add_url(nb_id, url)
36
+ result = await client.chat.ask(nb_id, question)
37
+ ```
38
+
39
+ ### Data Structures
40
+ ```python
41
+ @dataclass
42
+ class Notebook:
43
+ id: str
44
+ title: str
45
+ created_at: Optional[datetime] = None
46
+
47
+ @classmethod
48
+ def from_api_response(cls, data: list[Any]) -> "Notebook": ...
49
+ ```
50
+
51
+ ### Enums for Constants
52
+ ```python
53
+ class RPCMethod(str, Enum):
54
+ LIST_NOTEBOOKS = "wXbhsf"
55
+
56
+ class AudioFormat(int, Enum):
57
+ DEEP_DIVE = 1
58
+ ```
59
+
60
+ ### Error Handling
61
+ ```python
62
+ class RPCError(Exception):
63
+ def __init__(self, message: str, rpc_id: Optional[str] = None, code: Optional[Any] = None):
64
+ self.rpc_id, self.code = rpc_id, code
65
+ super().__init__(message)
66
+
67
+ raise RPCError(f"No result found for RPC ID: {rpc_id}", rpc_id=rpc_id)
68
+ raise ValueError(f"Invalid YouTube URL: {url}") # For validation
69
+ ```
70
+
71
+ ### Docstrings
72
+ ```python
73
+ def decode_response(raw_response: str, rpc_id: str, allow_null: bool = False) -> Any:
74
+ """Complete decode pipeline: strip prefix -> parse chunks -> extract result.
75
+
76
+ Args:
77
+ raw_response: Raw response text from batchexecute
78
+ rpc_id: RPC method ID to extract result for
79
+ allow_null: If True, return None instead of raising when null
80
+
81
+ Returns:
82
+ Decoded result data
83
+
84
+ Raises:
85
+ RPCError: If RPC returned an error or result not found
86
+ """
87
+ ```
88
+
89
+ ## Testing Patterns
90
+
91
+ ```python
92
+ # Class-based for related tests
93
+ class TestDecodeResponse:
94
+ def test_full_decode_pipeline(self): ...
95
+
96
+ # Markers
97
+ @pytest.mark.e2e # End-to-end (requires auth)
98
+ @pytest.mark.slow # Long-running (audio/video)
99
+ @pytest.mark.asyncio # Async tests
100
+
101
+ # Async tests
102
+ @pytest.mark.asyncio
103
+ async def test_list_notebooks(self, client):
104
+ notebooks = await client.notebooks.list()
105
+ assert isinstance(notebooks, list)
106
+ ```
107
+
108
+ ## Do NOT
109
+
110
+ - Suppress type errors with `# type: ignore`
111
+ - Commit `.env` files or credentials
112
+ - Add dependencies without updating `pyproject.toml`
113
+ - Change RPC method IDs without verifying via network capture
114
+ - Delete or modify e2e tests without running them
115
+ - Create documentation files without following CONTRIBUTING.md rules
@@ -0,0 +1,65 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [0.1.0] - 2026-01-08
9
+
10
+ ### Added
11
+ - Initial release of `notebooklm-py` - unofficial Python client for Google NotebookLM
12
+ - Full notebook CRUD operations (create, list, rename, delete)
13
+ - **Research polling CLI commands** for LLM agent workflows:
14
+ - `notebooklm research status` - Check research progress (non-blocking)
15
+ - `notebooklm research wait --import-all` - Wait for completion and import sources
16
+ - `notebooklm source add-research --no-wait` - Start deep research without blocking
17
+ - **Multi-artifact downloads** with intelligent selection:
18
+ - `download audio`, `download video`, `download infographic`, `download slide-deck`
19
+ - Multiple artifact selection (--all flag)
20
+ - Smart defaults and intelligent filtering (--latest, --earliest, --name, --artifact-id)
21
+ - File/directory conflict handling (--force, --no-clobber, auto-rename)
22
+ - Preview mode (--dry-run) and structured output (--json)
23
+ - Source management:
24
+ - Add URL sources (with YouTube transcript support)
25
+ - Add text sources
26
+ - Add file sources (PDF, TXT, MD, DOCX) via native upload
27
+ - Delete sources
28
+ - Rename sources
29
+ - Studio artifact generation:
30
+ - Audio overviews (podcasts) with 4 formats and 3 lengths
31
+ - Video overviews with 9 visual styles
32
+ - Quizzes and flashcards
33
+ - Infographics, slide decks, and data tables
34
+ - Study guides, briefing docs, and reports
35
+ - Query/chat interface with conversation history support
36
+ - Research agents (Fast and Deep modes)
37
+ - Artifact downloads (audio, video, infographics, slides)
38
+ - CLI with 27 commands
39
+ - Comprehensive documentation (API, RPC, examples)
40
+ - 96 unit tests (100% passing)
41
+ - E2E tests for all major features
42
+
43
+ ### Fixed
44
+ - Audio overview instructions parameter now properly supported at RPC position [6][1][0]
45
+ - Quiz and flashcard distinction via title-based filtering
46
+ - Package renamed from `notebooklm-automation` to `notebooklm`
47
+ - CLI module renamed from `cli.py` to `notebooklm_cli.py`
48
+ - Removed orphaned `cli_query.py` file
49
+
50
+ ### ⚠️ Beta Release Notice
51
+
52
+ This is the initial public release of `notebooklm-py`. While core functionality is tested and working, please note:
53
+
54
+ - **RPC Protocol Fragility**: This library uses undocumented Google APIs. Method IDs can change without notice, potentially breaking functionality. See [Troubleshooting](docs/troubleshooting.md) for debugging guidance.
55
+ - **Unofficial Status**: This is not affiliated with or endorsed by Google.
56
+ - **API Stability**: The Python API may change in future releases as we refine the interface.
57
+
58
+ ### Known Issues
59
+
60
+ - **RPC method IDs may change**: Google can update their internal APIs at any time, breaking this library. Check the [RPC Capture](docs/reference/internals/rpc-capture.md) for how to identify and update method IDs.
61
+ - **Rate limiting**: Heavy usage may trigger Google's rate limits. Add delays between bulk operations.
62
+ - **Authentication expiry**: CSRF tokens expire after some time. Re-run `notebooklm login` if you encounter auth errors.
63
+ - **Large file uploads**: Files over 50MB may fail or timeout. Split large documents if needed.
64
+
65
+ [0.1.0]: https://github.com/teng-lin/notebooklm-py/releases/tag/v0.1.0
@@ -0,0 +1,168 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ **IMPORTANT:** Follow documentation rules in [CONTRIBUTING.md](CONTRIBUTING.md) - especially the file creation and naming conventions.
6
+
7
+ ## Project Overview
8
+
9
+ `notebooklm-py` is an unofficial Python client for Google NotebookLM that uses undocumented RPC APIs. The library enables programmatic automation of NotebookLM features including notebook management, source integration, AI querying, and studio artifact generation (podcasts, videos, quizzes, etc.).
10
+
11
+ **Critical constraint**: This uses Google's internal `batchexecute` RPC protocol with obfuscated method IDs that Google can change at any time. All RPC method IDs in `src/notebooklm/rpc/types.py` are undocumented and subject to breakage.
12
+
13
+ ## Development Commands
14
+
15
+ ```bash
16
+ # Create/recreate venv with uv (recommended - relocatable venvs)
17
+ uv venv .venv
18
+ uv pip install -e ".[all]"
19
+ playwright install chromium
20
+
21
+ # Activate virtual environment
22
+ source .venv/bin/activate
23
+
24
+ # Run all tests (excluding e2e by default)
25
+ pytest
26
+
27
+ # Run with coverage
28
+ pytest --cov
29
+
30
+ # Run e2e tests (requires authentication)
31
+ pytest tests/e2e -m e2e
32
+
33
+ # CLI testing
34
+ notebooklm --help
35
+ ```
36
+
37
+ ## Architecture
38
+
39
+ ### Layered Design
40
+
41
+ ```
42
+ CLI Layer (cli/)
43
+
44
+ Client Layer (client.py, _*.py APIs)
45
+
46
+ Core Layer (_core.py)
47
+
48
+ RPC Layer (rpc/)
49
+ ```
50
+
51
+ 1. **RPC Layer** (`src/notebooklm/rpc/`):
52
+ - `types.py`: All RPC method IDs and enums (source of truth)
53
+ - `encoder.py`: Request encoding
54
+ - `decoder.py`: Response parsing
55
+
56
+ 2. **Core Layer** (`src/notebooklm/_core.py`):
57
+ - HTTP client management
58
+ - RPC call abstraction
59
+ - Request counter handling
60
+
61
+ 3. **Client Layer** (`src/notebooklm/client.py`, `_*.py`):
62
+ - `NotebookLMClient`: Main async client with namespaced APIs
63
+ - `_notebooks.py`, `_sources.py`, `_artifacts.py`, etc.: Domain APIs
64
+
65
+ 4. **CLI Layer** (`src/notebooklm/cli/`):
66
+ - Modular Click commands
67
+ - `session.py`, `notebook.py`, `source.py`, `generate.py`, etc.
68
+
69
+ ### Key Files
70
+
71
+ | File | Purpose |
72
+ |------|---------|
73
+ | `client.py` | Main `NotebookLMClient` class |
74
+ | `_core.py` | HTTP and RPC infrastructure |
75
+ | `_notebooks.py` | `client.notebooks` API |
76
+ | `_sources.py` | `client.sources` API |
77
+ | `_artifacts.py` | `client.artifacts` API |
78
+ | `_chat.py` | `client.chat` API |
79
+ | `rpc/types.py` | RPC method IDs (source of truth) |
80
+ | `auth.py` | Authentication handling |
81
+ | `cli/` | CLI command modules |
82
+
83
+ ### Repository Structure
84
+
85
+ ```
86
+ src/notebooklm/
87
+ ├── __init__.py # Public exports
88
+ ├── client.py # NotebookLMClient
89
+ ├── auth.py # Authentication
90
+ ├── types.py # Dataclasses
91
+ ├── _core.py # Core infrastructure
92
+ ├── _notebooks.py # NotebooksAPI
93
+ ├── _sources.py # SourcesAPI
94
+ ├── _artifacts.py # ArtifactsAPI
95
+ ├── _chat.py # ChatAPI
96
+ ├── _research.py # ResearchAPI
97
+ ├── _notes.py # NotesAPI
98
+ ├── rpc/ # RPC protocol layer
99
+ │ ├── types.py # Method IDs and enums
100
+ │ ├── encoder.py # Request encoding
101
+ │ └── decoder.py # Response parsing
102
+ └── cli/ # CLI implementation
103
+ ├── __init__.py
104
+ ├── helpers.py # Shared utilities
105
+ ├── session.py # login, use, status, clear
106
+ ├── notebook.py # list, create, delete, rename
107
+ ├── source.py # source add, list, delete
108
+ ├── artifact.py # artifact commands
109
+ ├── generate.py # generate audio, video, etc.
110
+ ├── download.py # download commands
111
+ ├── chat.py # ask, configure, history
112
+ └── note.py # note commands
113
+ ```
114
+
115
+ ## API Patterns
116
+
117
+ ### Client Usage
118
+
119
+ ```python
120
+ # Correct pattern - uses namespaced APIs
121
+ async with await NotebookLMClient.from_storage() as client:
122
+ notebooks = await client.notebooks.list()
123
+ await client.sources.add_url(nb_id, url)
124
+ result = await client.chat.ask(nb_id, question)
125
+ status = await client.artifacts.generate_audio(nb_id)
126
+ ```
127
+
128
+ ### CLI Structure
129
+
130
+ Commands are organized as:
131
+ - **Top-level**: `login`, `use`, `status`, `clear`, `list`, `create`, `ask`
132
+ - **Grouped**: `source add`, `artifact list`, `generate audio`, `download video`, `note create`
133
+
134
+ ## Testing Strategy
135
+
136
+ - **Unit tests** (`tests/unit/`): Test encoding/decoding, no network
137
+ - **Integration tests** (`tests/integration/`): Mock HTTP responses
138
+ - **E2E tests** (`tests/e2e/`): Real API, require auth, marked `@pytest.mark.e2e`
139
+
140
+ ### E2E Test Status
141
+
142
+ - ✅ Notebook operations (list, create, rename, delete)
143
+ - ✅ Source operations (add URL/text/YouTube, rename)
144
+ - ✅ Download operations (audio, video, infographic, slides)
145
+ - ⚠️ Artifact generation may fail due to rate limiting
146
+
147
+ ## Common Pitfalls
148
+
149
+ 1. **RPC method IDs change**: Check network traffic and update `rpc/types.py`
150
+ 2. **Nested list structures**: Params are position-sensitive. Check existing implementations.
151
+ 3. **Source ID nesting**: Different methods need `[id]`, `[[id]]`, `[[[id]]]`, or `[[[[id]]]]`
152
+ 4. **CSRF tokens expire**: Use `client.refresh_auth()` or re-run `notebooklm login`
153
+ 5. **Rate limiting**: Add delays between bulk operations
154
+
155
+ ## Documentation
156
+
157
+ All docs use lowercase-kebab naming in `docs/`:
158
+ - `docs/getting-started.md` - Installation and first workflow
159
+ - `docs/cli-reference.md` - CLI commands
160
+ - `docs/python-api.md` - Python API reference
161
+ - `docs/configuration.md` - Storage and settings
162
+ - `docs/troubleshooting.md` - Known issues
163
+ - `docs/contributing/` - Architecture, debugging, testing guides
164
+
165
+ ## When to Suggest CLI vs API
166
+
167
+ - **CLI**: Quick tasks, shell scripts, LLM agent automation
168
+ - **Python API**: Application integration, complex workflows, async operations