Observability & Custom Retry Gating¶
TusClient exposes three lightweight hooks for tracing requests and shaping retry behaviour. They cost nothing when unset.
before_request and after_response¶
def before(method, url, headers):
print(f"-> {method} {url}")
def after(method, url, status):
print(f"<- {method} {url} {status}")
client = TusClient(
"http://localhost:8080/files",
before_request=before,
after_response=after,
)
before_request fires before every HTTP request the client issues: the creation POST (plain, partial and final), every HEAD (offset checks, get_upload_info, get_metadata), every PATCH, OPTIONS (get_server_info) and DELETE. after_response fires after each response with its status code. For uploader-routed requests (the offset HEAD and every PATCH) it fires only on success, in both the sync and the async client; for client-level calls (create, final, info, metadata, server info, delete) the sync client also reaches it only for non-error responses, since urlopen raises on 4xx/5xx, while the async client reports every status. They run on the calling thread, synchronously — keep them cheap (logging, metrics, span creation) and avoid blocking I/O.
The hooks are forwarded to any Uploader you obtain from TusClient.create_uploader(), so chunk PATCHes are observed too.
on_should_retry¶
def should_retry(err: Exception, attempt: int) -> bool:
if isinstance(err, PermissionError):
return False # don't retry auth failures
return attempt < 5 # cap above the configured max_retries
client = TusClient(
"http://localhost:8080/files",
max_retries=10,
on_should_retry=should_retry,
)
on_should_retry is consulted before every retry attempt during a chunk upload. Returning False aborts retry immediately and surfaces a TusUploadFailed. Returning True falls through to the standard exponential-backoff schedule.
The hook receives the original exception and the 1-indexed attempt number, so it can apply domain rules ("don't retry quota errors", "give the network exactly one extra try") without touching the library's retry math.
Examples¶
examples/client/hooks.py— full hook set wired into a TusClient.