Errors and utilities

Retries

The client retries 408, 429 and 5xx responses, dropped connections and timeouts, with exponential backoff, and honors retry-after-ms and retry-after. It doesn't retry an error whose body says "retryable": false. Every retry of a document create or upload reuses the same Idempotency-Key, so it never starts or bills a second job.

RetryPolicy is a frozen dataclass:

FieldTypeDefaultDescription
max_retriesint2Retries after the first attempt. 0 disables retries.
backoff_initialfloat0.5First delay in seconds, doubled on each retry. 0 disables backoff.
backoff_maxfloat5.0Longest delay in seconds. 0 disables backoff.
backoff_jitterfloat0.25Fraction of each delay randomly taken off, from 0 to 1.
http_statusesset[int]{408, 429, 500, ..., 599}Statuses that are retried.
respect_retry_afterboolTrueWait what retry-after-ms or retry-after says instead of the backoff.
api_connection_errorboolTrueRetry NaceAPIConnectionError.
api_timeout_errorboolTrueRetry NaceAPITimeoutError.
exceptionsset[type[BaseException]]set()More exception types to retry.
predicateCallable[[BaseException], bool] | NoneNoneCalled with each error; True retries it too.
timeoutfloat | None30.0Total budget in seconds for one call: every attempt plus the waits between them. None removes it.

The budget counts from the first attempt. Before each retry the client adds the wait to the time already spent, and if that reaches timeout, it stops and raises the last error. So with the defaults, an attempt that fails after 30 seconds or more is not retried: a request that runs into the 60-second timeout, or a 529 that came after Drex's 55-second wait for the model. A retry-after longer than what is left of the budget isn't waited out either: the error is raised at once. To retry those, raise the budget above your timeout:

from nace_sdk import NaceClient, RetryPolicy

client = NaceClient(timeout=60, retry=RetryPolicy(max_retries=3, timeout=200))

A retry= on one call replaces the client's policy for that call. The client doesn't expose its policy, so build one from the policy you passed to the client (or from RetryPolicy()) with dataclasses.replace(policy, max_retries=0). A negative max_retries, a negative or infinite delay, a jitter outside 0 to 1, or a nonpositive timeout raises NaceError. Retried attempts carry an X-Nace-Retry-Count header. The job event stream and a download cut off midway are never retried, and saved-schema creates aren't retried unless you pass retry; see Progress events, Download a file and Saved schemas.