tauopt._http#

httpx transport for the hosted driver: Bearer auth + bounded retries.

Retries: 429 and 5xx only, bounded attempts, honoring Retry-After when present. A bandwidth-full 429 is an EXPECTED signal under parallelism – callers that want to wait longer than the bounded budget loop at their own layer (see examples/parallel_workers.py). A POST retries a 429 and the typed PRE-COMMIT 503s named in _POST_RETRYABLE_503_TYPES – never any other 5xx (it may follow a server-side commit).

Module Contents#

API#

exception tauopt._http.ApiError(status_code: int, error_type: str, message: str, details: dict | None = None, headers: Any = None)#

Bases: RuntimeError

Non-2xx API response, surfaced with the server’s error payload.

details: a structured machine-readable payload riding the error – the local driver’s draftless terminal asks attach the boundary’s dedup record here (typed refusals included), so audit surfaces never parse free-form message text.

headers carries the final HTTP response’s headers on transport-raised errors (empty mapping from the local driver), so a caller catching a final 429/503 can read Retry-After – via the parsed :attr:retry_after – after the transport’s own bounded retries gave up. The mapping is the response’s own headers object (aliased, not copied); treat it as read-only.

Initialization

Initialize self. See help(type(self)) for accurate signature.

property retry_after: float | None#

Parsed Retry-After seconds from the final response (None when the header is absent, not a plain number, negative, or non-finite – the HTTP-date form is not parsed, matching the transport’s own retry handling; a poisoned value must never reach a caller’s backoff).

exception tauopt._http.OptimizationComplete#

Bases: Exception

The optimization is COMPLETE – a terminal state, not a failure (the Ax completion-ladder shape). Catch this to handle every terminal state with one except-clause – space exhaustion today, budget-done/convergence-stop tomorrow – and narrow on the subclass when the WHICH matters::

try:
    sug = client.suggest(exp_id)
except OptimizationComplete:
    ...  # done -- read the best point

Wire-mapped terminal errors are always DUAL-LINEAGE (they also subclass :class:ApiError), so pre-flip except ApiError handlers keep working unchanged.

Initialization

Initialize self. See help(type(self)) for accurate signature.

exception tauopt._http.TerminalApiError(status_code: int, error_type: str, message: str, details: dict | None = None, headers: Any = None)#

Bases: tauopt._http.OptimizationComplete, tauopt._http.ApiError

A wire-mapped TERMINAL error: dual-lineage by construction – the full :class:ApiError surface (status_code / error_type / details) plus the :class:OptimizationComplete catch. Unknown FUTURE error types carrying details.terminal: true map here, so new server-side terminal states are catchable by the base without a client upgrade.

Initialization

Initialize self. See help(type(self)) for accurate signature.

exception tauopt._http.SpaceExhausted(status_code: int, error_type: str, message: str, details: dict | None = None, headers: Any = None)#

Bases: tauopt._http.TerminalApiError

PROVEN exhaustion: every input-feasible point is taken – the search space is complete, by construction (wire error_type: "space_exhausted", non-retryable 409). details.dedup carries the proof receipt (exhaust_proof / proof_method / universe_size); a same-state re-ask returns the same answer (P4) – observe or close pending work, or continue through an authorized replication intent.

Initialization

Initialize self. See help(type(self)) for accurate signature.

exception tauopt._http.AskDeadlineExceeded(message: str, *, point: str, max_wait_s: float | None, elapsed_s: float, rung: str | None = None, status_code: int = 503, headers: Any = None, details: dict | None = None, stage: str | None = None, backstop_s: float | None = None, backstop_source: str | None = None)#

Bases: tauopt._http.ApiError

Caps-mode request-deadline refusal, the one engine error that is a wire error on both planes: 503 ask_deadline_exceeded, deliberately no Retry-After (a caps re-ask repeats deterministic work, so waiting fixes nothing). Raised by the engine’s ask when timebox_mode is caps and the ask’s max_wait_s expired at a rung boundary (before work) or at the single post-completion delivery decision (after work) – the only two refusal points. No answer, no substitution, no state advance; the computed drafts (delivery case) are discarded, never exposed (carrying them would BE delivery). Distinct from TimeboxExceeded by design and never caught by the P6 ladder machinery (pinned): work exhaustion is not an exception and a deadline must never buy a different rung’s answer.

The refusal receipt rides the exception twice over – as attributes, point ("rung_boundary" | "delivery"), max_wait_s, elapsed_s, and rung (the rung about to run / the rung whose answer was withheld), and as details (the same four keys: the payload the hosted service sends and the transport reads back; on the hosted plane any further key the service’s body carries beside them rides along). The local driver raises it unchanged (it already carries the wire shape); the hosted driver raises it from the service’s 503 body when that body carries the receipt. On the engine path prior failed-rung evidence chains via __cause__ (the sink dies with the ask; the exception is the record’s carrier).

Initialization

Initialize self. See help(type(self)) for accurate signature.

exception tauopt._http.BackstopExceeded(message: str, *, stage: str, max_wait_s: float | None, backstop_s: float, elapsed_s: float, backstop_source: str | None = 'formula', rung: str | None = None, status_code: int = 503, headers: Any = None, details: dict | None = None)#

Bases: tauopt._http.AskDeadlineExceeded

The supervisor’s refusal: the SAME 503 ask_deadline_exceeded wire class with point = "backstop" – the ask did not answer within B(max_wait_s) = max(1.25 W, W + 3 s) (the protocol constants of tauopt._backstop), so a typed refusal was sent and the work abandoned or killed behind it. Additive to the engine’s two refusal points, never a substitute: a delivered answer is byte-identical to the answer the same ask delivers without a supervisor. stage names where the budget ran out: "ask" (the worker was running the ask), "warmup" (the worker had not handshaken), "worker_died" (the worker closed the pipe without an answer: details.exit_code), "reap" (too many retired workers refuse to die: details.unreaped_pids; restart the process), "abandoned" (the thread primitive’s registry is at its cap; restart the process); backstop_s is the backstop the ask was refused at and backstop_source the binding term ("formula"; "ceiling" on a hosted plane whose ceiling bound). No Retry-After: a re-ask of a hung computation repeats it. rung is None (the engine never reached a refusal point of its own).

Initialization

Initialize self. See help(type(self)) for accurate signature.