Commit Graph

3 Commits

Author SHA1 Message Date
Paul Huliganga 2b3413670f feat: apply retry-with-backoff to all outbound API calls
Add RetryableHTTPError and raise_for_retryable_status() to retry.py, then
wire up @retry_with_backoff across all network-touching functions:

- All 5 public Adobe Sign API functions in adobe_api.py
- upload_template() and find_existing_template() in upload_docusign_template.py

raise_for_retryable_status() distinguishes transient errors (429, 500, 502,
503, 504) from auth/client errors — only transient errors are retried.
Auth refresh functions are intentionally left undecorated since a 401 there
means bad credentials, not a transient failure.

Backoff: 1s → 2s → 4s, max 16s, max 3 retries (131 tests passing).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-23 09:51:28 -04:00
Paul Huliganga 9c6c01d619 fix: correct Adobe Sign token refresh endpoint and add auth error handling
Adobe Sign uses a non-standard separate endpoint for refresh:
/oauth/v2/refresh (not /oauth/v2/token). Using the wrong endpoint
returned a misleading "Invalid grant_type refresh_token" error.

Also:
- Remove redirect_uri from refresh requests (not required)
- Add clear RuntimeError message directing user to re-authenticate
- Validate access_token is non-empty before saving in adobe_auth.py
- Log token lengths and exchange response keys on successful auth

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 10:10:12 -04:00
Paul Huliganga 343955241d feat: Adobe Sign OAuth client and API wrapper
auth_adobe.py — one-time browser Auth Code Grant flow; saves access and
refresh tokens to .env. Targets the EU2 shard.

adobe_api.py — thin API client with auto token refresh on 401. Supports
GET, POST (JSON and multipart), PUT, and binary download.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 19:44:43 -04:00