Only if the operation is idempotent. A timeout doesn’t tell you whether the payment went through, so a blind retry can charge twice. Send an idempotency key that stays the same across retries, so the server returns the first result instead of repeating the action, as Stripe’s API does; reads, PUT and DELETE are idempotent by HTTP’s definition. Retry with capped exponential backoff and jitter so that clients don’t retry in lockstep.
import random, time, uuid
def call_with_retries(tool, args, attempts=4, base=0.5, cap=8.0):
key = str(uuid.uuid4()) # the same key on every retry
for attempt in range(attempts):
try:
return tool(**args, idempotency_key=key, timeout=10)
except TimeoutError:
if attempt == attempts - 1:
raise # give up and escalate
time.sleep(random.uniform(0, min(cap, base * 2 ** attempt))) # backoff with jitter
Set each tool’s timeout from the downstream service’s latency percentiles, as AWS describes (for example p99.9), not from a guess.
Stripe API reference: Idempotent requestsRFC 9110, HTTP Semantics, section 9.2.2: Idempotent MethodsAmazon Builders' Library: Timeouts, retries and backoff with jitter
Practise it with Prism