Skip to content

Use single proxy value for httpx#1980

Merged
saleweaver merged 1 commit intomasterfrom
codex/fix-bug-with-reports.get_report_document-vofa5t
Feb 5, 2026
Merged

Use single proxy value for httpx#1980
saleweaver merged 1 commit intomasterfrom
codex/fix-bug-with-reports.get_report_document-vofa5t

Conversation

@saleweaver
Copy link
Owner

@saleweaver saleweaver commented Feb 5, 2026

Motivation

  • Simplify proxy handling for httpx.Client by always passing a single proxy string because httpx expects a proxy string rather than a mapping.
  • Replace previous mapping-selection logic with behavior matching actual usage: choose one proxy from a list/tuple or use the provided string.

Description

  • Add _httpx_client_kwargs(*, proxies=None, verify=True, timeout=None) in sp_api/base/_transport_httpx.py that returns a dict with a single proxy string, selecting one at random if proxies is a list or tuple and otherwise using the provided value.
  • Remove the mapping preference/inspection logic and ensure HttpxTransport constructs its client via **_httpx_client_kwargs(...) so proxy is always a single string.
  • Update synchronous download usages in sp_api/api/reports/reports.py and sp_api/api/data_kiosk/data_kiosk.py to use **_httpx_client_kwargs(...) instead of passing proxies directly.
  • Add tests in tests/api/test_httpx_transport.py covering a single proxy string and selection from a list via random.choice (monkeypatched in the test).

Testing

  • Ran pytest tests/api/test_httpx_transport.py and the suite passed with 2 passed tests.

Codex Task

Summary by Sourcery

Unify httpx client proxy handling around a single proxy value and apply it consistently across HTTP transport and synchronous document downloads.

Enhancements:

  • Introduce a helper to build httpx.Client keyword arguments that always resolve to a single proxy value, randomly selecting from a list or tuple when multiple proxies are provided.
  • Update HttpxTransport and synchronous report/data kiosk download code paths to construct httpx.Client instances via the shared helper for consistent proxy, timeout, and verify configuration.

Tests:

  • Add unit tests verifying that the httpx client kwargs helper preserves a single proxy string and correctly selects a proxy from a list using random.choice.

@sourcery-ai
Copy link
Contributor

sourcery-ai bot commented Feb 5, 2026

Reviewer's Guide

Refactors httpx client construction to always pass a single proxy string via a shared helper, updates the few direct httpx.Client call sites to use it, and adds focused tests for the new behavior.

Class diagram for HttpxTransport and httpx.Client construction

classDiagram
    class HttpxTransport {
        +timeout
        +proxies
        +proxy
        +verify
        -_client
        +HttpxTransport(timeout, proxies, proxy, verify, client)
        +request(method, url, params, data, content, headers)
    }

    class _httpx_client_kwargs {
        <<function>>
        +_httpx_client_kwargs(proxies, verify, timeout) dict
    }

    class DataKiosk {
        +proxies
        +verify
        +get_document(download, file, **kwargs)
    }

    class Reports {
        +proxies
        +verify
        +get_report_document(download, file, timeout, stream, **kwargs)
    }

    HttpxTransport ..> _httpx_client_kwargs : uses for httpx.Client kwargs
    DataKiosk ..> _httpx_client_kwargs : uses for httpx.Client kwargs
    Reports ..> _httpx_client_kwargs : uses for httpx.Client kwargs

    class httpx_Client {
        +Client(proxy, verify, timeout)
        +get(url)
        +stream(method, url)
    }

    HttpxTransport ..> httpx_Client : constructs
    DataKiosk ..> httpx_Client : constructs with _httpx_client_kwargs
    Reports ..> httpx_Client : constructs with _httpx_client_kwargs
Loading

Flow diagram for _httpx_client_kwargs proxy and timeout selection

flowchart TD
    A_start[Start _httpx_client_kwargs] --> B_init[Initialize client_kwargs with verify]
    B_init --> C_timeout_check{Is timeout provided?}
    C_timeout_check -- Yes --> D_set_timeout[Set client_kwargs.timeout]
    C_timeout_check -- No --> E_skip_timeout[Skip setting timeout]
    D_set_timeout --> F_proxies_check{Are proxies provided?}
    E_skip_timeout --> F_proxies_check

    F_proxies_check -- No --> J_return_no_proxy[Return client_kwargs without proxy]
    F_proxies_check -- Yes --> G_type_check{Are proxies list or tuple?}

    G_type_check -- Yes --> H_choice[Select proxy_value with random.choice]
    G_type_check -- No --> I_direct[Set proxy_value to proxies]

    H_choice --> K_set_proxy[Set client_kwargs.proxy to proxy_value]
    I_direct --> K_set_proxy

    K_set_proxy --> L_return_with_proxy[Return client_kwargs with proxy]
    J_return_no_proxy --> M_end[End]
    L_return_with_proxy --> M_end
Loading

File-Level Changes

Change Details Files
Introduce a shared helper to build httpx.Client keyword arguments and ensure only a single proxy string is passed.
  • Add _httpx_client_kwargs that builds a kwargs dict with verify, optional timeout, and a single proxy value
  • Support proxies as a list or tuple by selecting one at random, or as a single string/value passed through unchanged
  • Use the helper in HttpxTransport so the internal httpx.Client is consistently configured via **_httpx_client_kwargs
sp_api/base/_transport_httpx.py
Update synchronous report and data kiosk downloads to use the new httpx client helper for proxy handling.
  • Import _httpx_client_kwargs alongside httpx in data_kiosk and reports modules
  • Replace direct proxies/verify/timeout keyword arguments to httpx.Client with **_httpx_client_kwargs calls in download contexts
sp_api/api/data_kiosk/data_kiosk.py
sp_api/api/reports/reports.py
Add tests covering the new httpx client kwargs helper and proxy selection behavior.
  • Test that a single proxy string is passed through and verify/timeout are preserved
  • Test that when proxies is a list, the helper uses random.choice to select the proxy, with choice monkeypatched for determinism
tests/api/test_httpx_transport.py

Possibly linked issues

  • #Client.__init__() got an unexpected keyword argument 'proxies': The PR fixes the TypeError by changing sync report/document downloads to use a valid 'proxy' arg for httpx.Client.

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey - I've found 2 issues, and left some high level feedback:

  • Consider handling the case where proxies is an empty list/tuple in _httpx_client_kwargs, since random.choice([]) will raise an IndexError and could surface as a hard-to-diagnose runtime error.
  • It may be helpful to add simple type hints to _httpx_client_kwargs (particularly for proxies and the return type) to make the expected proxy formats and behavior clearer at call sites in HttpxTransport, DataKiosk, and Reports.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Consider handling the case where `proxies` is an empty list/tuple in `_httpx_client_kwargs`, since `random.choice([])` will raise an `IndexError` and could surface as a hard-to-diagnose runtime error.
- It may be helpful to add simple type hints to `_httpx_client_kwargs` (particularly for `proxies` and the return type) to make the expected proxy formats and behavior clearer at call sites in `HttpxTransport`, `DataKiosk`, and `Reports`.

## Individual Comments

### Comment 1
<location> `sp_api/base/_transport_httpx.py:6-11` </location>
<code_context>
 import httpx


+def _httpx_client_kwargs(*, proxies=None, verify=True, timeout=None):
+    client_kwargs = {"verify": verify}
+    if timeout is not None:
+        client_kwargs["timeout"] = timeout
+    if proxies is not None:
+        if isinstance(proxies, (list, tuple)):
+            proxy_value = random.choice(proxies)
+        else:
</code_context>

<issue_to_address>
**issue:** Guard against empty proxy sequences before calling `random.choice`.

If `proxies` is an empty list/tuple, `random.choice(proxies)` will raise `IndexError`. Consider either skipping proxy configuration when the sequence is empty or raising a clearer error by validating that it’s non-empty (e.g. `if proxies:`) before calling `random.choice` or at the call site.
</issue_to_address>

### Comment 2
<location> `tests/api/test_httpx_transport.py:3` </location>
<code_context>
+import httpx
+
 from sp_api.base import Client, sp_endpoint, fill_query_params, ApiResponse
+from sp_api.base._transport_httpx import _httpx_client_kwargs


</code_context>

<issue_to_address>
**suggestion (testing):** Add unit tests that exercise `HttpxTransport` itself, not just the helper function

These tests only cover `_httpx_client_kwargs`, while the behavior change is in `HttpxTransport`. Please add tests that construct `HttpxTransport` with various `proxy`/`proxies`/`timeout`/`verify` combinations and assert that `httpx.Client` is called with the expected kwargs (e.g., by monkeypatching `httpx.Client`). This will verify the helper is wired correctly and that proxy precedence and defaults behave as intended.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +6 to +11
def _httpx_client_kwargs(*, proxies=None, verify=True, timeout=None):
client_kwargs = {"verify": verify}
if timeout is not None:
client_kwargs["timeout"] = timeout
if proxies is not None:
if isinstance(proxies, (list, tuple)):
Copy link
Contributor

Choose a reason for hiding this comment

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

issue: Guard against empty proxy sequences before calling random.choice.

If proxies is an empty list/tuple, random.choice(proxies) will raise IndexError. Consider either skipping proxy configuration when the sequence is empty or raising a clearer error by validating that it’s non-empty (e.g. if proxies:) before calling random.choice or at the call site.

@@ -0,0 +1,24 @@
import random

from sp_api.base._transport_httpx import _httpx_client_kwargs
Copy link
Contributor

Choose a reason for hiding this comment

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

suggestion (testing): Add unit tests that exercise HttpxTransport itself, not just the helper function

These tests only cover _httpx_client_kwargs, while the behavior change is in HttpxTransport. Please add tests that construct HttpxTransport with various proxy/proxies/timeout/verify combinations and assert that httpx.Client is called with the expected kwargs (e.g., by monkeypatching httpx.Client). This will verify the helper is wired correctly and that proxy precedence and defaults behave as intended.

@saleweaver saleweaver merged commit dc4b889 into master Feb 5, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant