v1: remove client.rpc_call and the Android Web compatibility sidecar
Parent: #2376. Replaces the remaining work from #2319.
#2319’s 0.x work is already on main. Do not re-implement client.raw or the lazy sidecar. Do not trust #2319’s “Current findings”: they describe pre-#2355 assembly (Android always constructing a Web Kernel and opening httpx on __aenter__). That is no longer true.
Committed contract: ADR-0035 (2026-09-03 note) and docs/architecture.md (deprecated rpc_call + inert sidecar).
What 0.x already has
- Web:
client.raw.call(RPCMethod, params, ...)reuses the selected WebRpcExecutor - Android:
client.raw.unary(GrpcUnaryMethod, request)andclient.raw.unary_stream(...)throughAndroidSession(fixednotebooklm-pa.googleapis.com:443, library-owned bearer, defaultReplayPolicy.NEVER, bounded stream bytes) NotebookLMClient.rpc_callstill exists. First call emitsclient_rpc_call_weborclient_rpc_call_android. On Android it materialises_client_compat.LazyWebSidecar(Web cookies + CSRF from the 0.x homepage bootstrap). The sidecar starts no keepalive. Typed Android namespaces never use it.- Descriptors live in public
notebooklm.raw(WebRawAPI,AndroidRawAPI,GrpcUnaryMethod,GrpcUnaryStreamMethod,ReplayPolicy). Generated_android.protostays private.
Those warnings are registered since=0.9.0 in source. v0.9.0 has no GitHub release/tag. Removal cannot share a release with the first published warning.
What v1 deletes
-
NotebookLMClient.rpc_call(both backends) -
_client_compat.LazyWebSidecarandbuild_compatibility_runtime - Any Android construction/open/refresh path that still allocates Web
Kernel,RpcExecutor, Web middleware,ReqidCounter, Web upload pipeline, or Web namespace adapters - Homepage GET / Web cookie parse whose only consumer was the hatch (this lands with #2377: Android stored construction must not fetch CSRF “just in case”)
After the cut, an Android client that never used rpc_call must satisfy:
- no
notebooklm._web*import in a clean process afterimport notebooklm+ Android construct/open - no
httpx.AsyncClientfor NotebookLM batchexecute - no Web keepalive task
- typed
client.notebooks/sources/ … still the Android implementations
Callers who need both gRPC and batchexecute open two clients.
Replacement (already shipped; document at the cut)
# Web
await client.raw.call(RPCMethod.GET_NOTEBOOK, [notebook_id])
# Android
response = await client.raw.unary(get_project, GetProjectRequest(project_id=notebook_id))
async for message in client.raw.unary_stream(method, request):
...Do not invent a backend-neutral call() that mixes RPCMethod JSON params with protobuf.
Safety (keep; do not regress)
- Raw gRPC target is fixed; caller cannot redirect the NotebookLM bearer
- Caller metadata cannot override
authorizationor other library-owned headers - Unary replay stays opt-in
ReplayPolicy.SAFE_READ - Finite default unary-stream byte cap
- No client-streaming / bidi unless a real NotebookLM method requires it
Tests / docs
- Android lifecycle ownership tuple contains only shared + Android participants
- Guardrail: no
_web↔_androidimport edges; composition allowlists shrink (sidecar importer goes away) - API-compat: exact
rpc_callmethod removal allowlist; no stale allowance for the privateLazyWebSidecarclass - Behavioral runway for “Android
from_storageno longer hits the homepage” docs/deprecations.md,docs/python-api.md,docs/architecture.md, changelog: hatch is gone;client.rawis the advanced surface; Google method/schema stability is not promised
Gate
Same as #2376: published warning release + one MINOR, then remove. Same v1.0.0 cut as #2377 is fine; do not ship an intermediate where rpc_call is gone but Android construction still builds Web objects “for compatibility.”
Source: teng-lin/notebooklm-py