Skip to main content

nimble-http

Async HTTP client for service-to-service calls: fully typed, timeouts on every request, bounded retries for transient failures only, and typed errors that tell a caller whether retrying is worth it.

Built on httpx. One AsyncHttpClient owns one connection pool — build it once per process (or per Lambda container) and share it.

Install

pip install nimble-http

Usage

from nimble_http import AsyncHttpClient, HttpMethod, HttpRequest, RetryPolicy


async def send() -> None:
    async with AsyncHttpClient(
        base_url="https://graph.facebook.com",
        headers={"authorization": "Bearer <token>"},
        read_timeout_seconds=10.0,
        retry=RetryPolicy(max_attempts=3),
    ) as client:
        response = await client.send(
            HttpRequest(
                method=HttpMethod.POST,
                url="/v26.0/<phone_number_id>/messages",
                json={"messaging_product": "whatsapp", "to": "<phone>"},
            ),
        )
        print(response.json())

Typed responses

from pydantic import BaseModel


class SendResult(BaseModel):
    messaging_product: str


result = await client.send_model(request, SendResult)

Concurrency

responses = await client.send_all(requests, max_concurrency=5)

send_all uses an asyncio.TaskGroup: the first failure cancels the rest and surfaces as an ExceptionGroup. Catch it with except*.

Streaming

async for chunk in client.stream(request):
    ...

body = await client.send_bytes(request)

Streaming is never retried once the response starts arriving.

Errors

Every failure is an HttpError. Check error.is_transient to decide whether to let a worker retry or to fail definitively.

Error Raised when is_transient
HttpTimeoutError connect/read/write timeout True
HttpTransportError DNS, TLS, connection, protocol failure True
HttpStatusError status outside 2xx (carries status_code, headers, content) only for 408, 425, 429, 5xx
HttpDecodeError body is not valid JSON / does not match the model False

Retries

RetryPolicy retries timeouts, transport errors and the status codes in retryable_status_codes (408, 425, 429, 500, 502, 503, 504 by default), with exponential backoff plus jitter. A Retry-After response header wins over the computed backoff, capped by backoff_max_seconds. Use NO_RETRY to disable.

Testing

Pass an httpx.AsyncBaseTransport to drive the client against a stub — no network, no monkeypatching:

import httpx

client = AsyncHttpClient(
    base_url="https://api.example.test",
    transport=httpx.MockTransport(lambda request: httpx.Response(200, json={})),
)

Breaking change in 0.2.0

The Requests, Session and Singleton classes are gone. They were untyped, shared a process-wide mutable session, had a fixed 600s timeout with no per-request override, and Requests.multiple recursed into itself. Migration:

0.1.0 0.2.0
Requests(raise_for_status=True) AsyncHttpClient(raise_for_status=True)
await r.single(payload) await client.send_json(HttpRequest(...))
await r.single_raw(payload) await client.send(HttpRequest(...))
await r.multiple(payloads) await client.send_all([HttpRequest(...), ...])
await r.single_bin(payload) await client.send_bytes(HttpRequest(...))

Metadata

Release files for nimble-http 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for nimble-http 0.2.0
File Size Uploaded Provenance Actions
nimble_http-0.2.0.tar.gz 6.6 kB Without provenance Details for nimble_http-0.2.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for nimble-http 0.2.0
File Interpreter ABI Platform Actions
nimble_http-0.2.0-py3-none-any.whl Python 3 none any Details for nimble_http-0.2.0-py3-none-any.whl

Total release size: 15.9 kB

Release files / nimble_http-0.2.0.tar.gz

Download URL nimble_http-0.2.0.tar.gz
Size 6.6 kB
Tags Source
SHA-256 checksum
How to use checksums
3c372376008b4bda1b53913d14bd45f2112cbdfc76b8d971acba6167b00553b3
BLAKE2b-256 checksum
How to use checksums
2873edf3c07d36f2332f2ec5d5d91d99af71f92e11e23d4885435e3189c42935
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/2.5.1 CPython/3.12.3 Linux/7.0.0-1017-azure

Release files / nimble_http-0.2.0-py3-none-any.whl

Download URL nimble_http-0.2.0-py3-none-any.whl
Size 9.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ee41cfbe53a30d63bc011848c02df440b6b700b55a905ebb2e9be1c44d5429b1
BLAKE2b-256 checksum
How to use checksums
a05f4c1d03aa298f629f363f34369e291c6b666d1e1029ab10c4e44d8e7d0660
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/2.5.1 CPython/3.12.3 Linux/7.0.0-1017-azure

Security for nimble-http 0.2.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page