v1: remove client.rpc_call and the Android Web compatibility sidecar

Author: teng-linCreated Sep 6, 2026Updated Sep 6, 2026
Labelsenhancementdo-not-implement-yetP2

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 Web RpcExecutor
  • Android: client.raw.unary(GrpcUnaryMethod, request) and client.raw.unary_stream(...) through AndroidSession (fixed notebooklm-pa.googleapis.com:443, library-owned bearer, default ReplayPolicy.NEVER, bounded stream bytes)
  • NotebookLMClient.rpc_call still exists. First call emits client_rpc_call_web or client_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.proto stays 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.LazyWebSidecar and build_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 after import notebooklm + Android construct/open
  • no httpx.AsyncClient for 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)

python
# 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 authorization or 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_android import edges; composition allowlists shrink (sidecar importer goes away)
  • API-compat: exact rpc_call method removal allowlist; no stale allowance for the private LazyWebSidecar class
  • Behavioral runway for “Android from_storage no longer hits the homepage”
  • docs/deprecations.md, docs/python-api.md, docs/architecture.md, changelog: hatch is gone; client.raw is 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.”