Skip to content

Add retry handling for 429 and transient errors#23

Open
Arittra-Bag wants to merge 2 commits into
mainfrom
feat/retry-handling
Open

Add retry handling for 429 and transient errors#23
Arittra-Bag wants to merge 2 commits into
mainfrom
feat/retry-handling

Conversation

@Arittra-Bag
Copy link
Copy Markdown
Collaborator

Closes: #15

Copilot AI review requested due to automatic review settings May 19, 2026 16:26
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds configurable retry/backoff support to the SDK’s request layer so transient failures (HTTP 429 / 5xx / connection errors) don’t immediately surface as user-visible errors, and introduces a dedicated RateLimitError to let callers handle rate limiting explicitly (closes #15).

Changes:

  • Introduces RateLimitError and exports it from the package.
  • Adds max_retries / backoff_base configuration to AtomicClient and propagates it into all resource clients.
  • Implements retry handling (429 w/ Retry-After, 5xx exponential backoff w/ jitter, and request exceptions) plus retry logging in ResourceClient.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

File Description
atomic_sdk/exceptions.py Adds RateLimitError with retry_after payload.
atomic_sdk/client.py Adds retry configuration to AtomicClient and forwards it to resource clients.
atomic_sdk/api/base.py Implements retry/backoff logic in _request and _get_raw, plus Retry-After parsing and retry logging.
atomic_sdk/__init__.py Exposes RateLimitError as part of the public API.
Comments suppressed due to low confidence (1)

atomic_sdk/api/base.py:34

  • ResourceClient.__init__ docstring lists only session, base_url, and client_id_or_name, but the signature now includes max_retries and backoff_base. Update the docstring so callers (and generated docs) reflect the new behavior/configuration.
    def __init__(
        self,
        session: requests.Session,
        base_url: str,
        client_id_or_name: str,
        max_retries: int = 3,
        backoff_base: float = 0.5,
    ):
        """
        Initializes the ResourceClient.

        Args:
            session: A requests.Session object configured with authentication.
            base_url: The base URL for the Atomic API.
            client_id_or_name: The client's identifier (name or ID).
        """

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread atomic_sdk/client.py
Comment thread atomic_sdk/api/base.py
Comment thread atomic_sdk/api/base.py
Comment thread atomic_sdk/exceptions.py Outdated
@Arittra-Bag
Copy link
Copy Markdown
Collaborator Author

Validated retry handling locally against the issue #15 acceptance criteria. The focused mocked tests cover 429 retry behavior with and without Retry-After, exhausted 429 classification as RateLimitError, 5xx retry behavior, max_retries=0, connection-error retries, immediate non-429 4xx failures, and _get_raw retry behavior.

Input

python -m pytest tests/test_retries.py -q

Output

...........                                                                                                                                            [100%]
====================================================================== warnings summary ======================================================================
atomic_sdk/models.py:132
  /workspace/release_20260121_175120/wp-cloud-atomic-sdk/atomic_sdk/models.py:132: PydanticDeprecatedSince20: Pydantic V1 style `@validator` validators are deprecated. You should migrate to Pydantic V2 style `@field_validator` validators, see the migration guide for more details. Deprecated in Pydantic V2.0 to be removed in V3.0. See Pydantic V2 Migration Guide at https://errors.pydantic.dev/2.13/migration/
    @validator("complete", pre=True)

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
11 passed, 1 warning in 0.15s

The warning is pre-existing in atomic_sdk/models.py and unrelated to this retry change.
Test File : test_retries.py

@Arittra-Bag
Copy link
Copy Markdown
Collaborator Author

Validated again and tests Passed Successfully.

====================================================================== warnings summary ======================================================================
atomic_sdk/models.py:132
  /workspace/release_20260121_175120/wp-cloud-atomic-sdk/atomic_sdk/models.py:132: PydanticDeprecatedSince20: Pydantic V1 style `@validator` validators are deprecated. You should migrate to Pydantic V2 style `@field_validator` validators, see the migration guide for more details. Deprecated in Pydantic V2.0 to be removed in V3.0. See Pydantic V2 Migration Guide at https://errors.pydantic.dev/2.13/migration/
    @validator("complete", pre=True)

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
15 passed, 1 warning in 0.11s

Test File : test_retries.py

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(base): 429 Retry-After + 5xx exponential backoff + RateLimitError

2 participants