HTTP-shape request envelope passed through the middleware chain. The chain wraps ``Kernel.post``. Every middleware sees an already-encoded HTTP request — encoding lives *above* the chain in :meth:`RpcExecutor.rpc_call`. RPC-level metadata that middlewares need (rpc method id, idempo
| 53 | |
| 54 | @dataclass(frozen=True) |
| 55 | class RpcRequest: |
| 56 | """HTTP-shape request envelope passed through the middleware chain. |
| 57 | |
| 58 | The chain wraps ``Kernel.post``. Every middleware sees an already-encoded |
| 59 | HTTP request — encoding lives *above* the chain in :meth:`RpcExecutor.rpc_call`. |
| 60 | RPC-level metadata that middlewares need (rpc |
| 61 | method id, idempotency, operation variant, log labels, build-request |
| 62 | callback, etc.) travels through :attr:`context`. |
| 63 | |
| 64 | Frozen: middlewares that want to alter the request build a new |
| 65 | :class:`RpcRequest` via :func:`dataclasses.replace`. The |
| 66 | :class:`AuthRefreshMiddleware` does exactly this when |
| 67 | rebuilding headers and URL after an auth refresh. |
| 68 | |
| 69 | :attr:`context` is mutable by reference (it's a plain :class:`dict`) and |
| 70 | is shared across the chain by design — see ADR-0009 §"Per-request |
| 71 | behavior". Middlewares that want isolation should make a shallow copy |
| 72 | before mutating. |
| 73 | """ |
| 74 | |
| 75 | url: str |
| 76 | """Fully-built ``batchexecute`` URL with ``authuser`` and ``_reqid`` set.""" |
| 77 | |
| 78 | headers: Mapping[str, str] |
| 79 | """HTTP headers for this attempt (auth headers, ``X-Goog-AuthUser``, …). |
| 80 | |
| 81 | Typed as :class:`~collections.abc.Mapping` (read-only protocol) rather |
| 82 | than :class:`dict` so the frozen-dataclass contract extends to the |
| 83 | header values: middlewares that want to add or alter headers build a |
| 84 | new :class:`RpcRequest` via :func:`dataclasses.replace` with a freshly |
| 85 | constructed dict (e.g. |
| 86 | ``dataclasses.replace(request, headers={**request.headers, "X-Foo": "1"})``). |
| 87 | Concrete :class:`dict` instances satisfy this annotation, so callers |
| 88 | that pass a literal ``{...}`` need no special treatment. |
| 89 | """ |
| 90 | |
| 91 | body: bytes |
| 92 | """Encoded ``batchexecute`` body bytes for this attempt.""" |
| 93 | |
| 94 | context: dict[str, Any] = field(default_factory=dict) |
| 95 | """RPC-level metadata the chain reads. |
| 96 | |
| 97 | The allowed vocabulary is exported as |
| 98 | :data:`ALLOWED_RPC_CONTEXT_KEYS` and mirrored in ADR-0009. Middlewares |
| 99 | and the transport terminal use the ``RPC_CONTEXT_*`` constants for |
| 100 | lookups and writes; adding a key requires updating this module, ADR-0009, |
| 101 | and the lint-style unit test that guards the vocabulary. |
| 102 | """ |
| 103 | |
| 104 | |
| 105 | @dataclass(frozen=True) |
no outgoing calls