Skip to content

feat(async): add HTTPClientConfig for tuning the async transport (closes #170)#171

Open
be-ant wants to merge 1 commit into
btoron:masterfrom
be-ant:feat/async-http-client-config
Open

feat(async): add HTTPClientConfig for tuning the async transport (closes #170)#171
be-ant wants to merge 1 commit into
btoron:masterfrom
be-ant:feat/async-http-client-config

Conversation

@be-ant
Copy link
Copy Markdown
Contributor

@be-ant be-ant commented May 25, 2026

Summary

  • Adds HTTPClientConfig — a Pydantic model with scalar fields only — that lets users tune the async transport without leaking httpx types into the public API.
  • Wires it through AsyncOFSC(..., http_config=...); defaults preserve today's behavior (HTTP/2 on, default pool/timeout, no retries).
  • Headline knob is max_concurrency, which translates to httpx.Limits(max_connections=N, max_keepalive_connections=N) — same semantics as aiohttp's TCPConnector(limit=N), so the abstraction survives a transport library swap.
  • Also exposes: timeout, max_retries (transport-level), proxy, verify_ssl, http2, follow_redirects, trust_env.
  • Adds 17 unit tests covering model validation and the wiring into httpx.AsyncClient.
  • README gains a short "HTTP Transport Configuration" subsection.

Closes #170.

Why library-neutral

HTTPClientConfig deliberately exposes only int / float / bool / str. The httpx.Limits / httpx.Timeout / httpx.AsyncHTTPTransport translation lives entirely inside AsyncOFSC._build_client_kwargs. If the project ever swaps httpx for another async HTTP client, the public surface here stays the same.

Example

from ofsc.async_client import AsyncOFSC, HTTPClientConfig

async with AsyncOFSC(
    clientID="...", companyName="...", secret="...",
    http_config=HTTPClientConfig(
        max_concurrency=20,
        timeout=30.0,
        max_retries=2,
    ),
) as client:
    workzones = await client.metadata.get_workzones()

Backward compatibility

http_config defaults to None. When unset, the constructor builds the client exactly as before. No existing call sites need to change.

Test plan

  • uv run pytest tests/async/test_async_http_config.py -v — 17 new tests pass
  • uv run pytest tests/async/test_async_ofsc.py -v — existing async client tests still pass
  • uv run pytest -m "not uses_real_data and not uses_local_data and not integration" — 443 passed, 8 skipped
  • uv run ruff check clean on changed files
  • uv run ruff format --check clean on changed files
  • Reviewer: run uv run pytest with live credentials to confirm no regression in credentialed tests

Closes btoron#170

Introduces a library-neutral HTTPClientConfig (scalar fields only —
int/float/bool/str) accepted by AsyncOFSC. The translation to
httpx.Limits / httpx.Timeout / httpx.AsyncHTTPTransport happens entirely
inside AsyncOFSC, so the public surface survives a future transport
library swap.

Exposed knobs (all optional; defaults preserve current behavior):
max_concurrency, timeout, max_retries, proxy, verify_ssl, http2,
follow_redirects, trust_env.
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(async): allow tuning HTTP transport (max_concurrency, timeout, retries, proxy, …) via a library-neutral HTTPClientConfig

1 participant