AtomHTTP
A modern, developer-friendly HTTP client for Python with a familiar API, powerful request handling, optional asynchronous support, and built-in tools for concurrent requests, uploads, downloads, retries, cookies, interceptors, streaming, and testing.
Designed to feel simple for everyday requests while providing the flexibility required for production applications.
Features
- Simple, familiar API — Make HTTP requests with a clean interface inspired by popular HTTP clients.
- Synchronous by default — Use AtomHTTP without configuring an event loop or asynchronous environment.
- Optional asynchronous API — Use
async/awaitwhen asynchronous workflows are required. - Concurrent requests — Execute multiple requests concurrently with a simple batch API.
- Request & response interceptors — Modify requests and responses globally or per client.
- Upload & download progress — Monitor transfer progress through incremental callbacks.
- Multipart & form submissions — Easily send form data and file uploads.
- Cookie management — Persistent cookie handling with automatic cookie propagation between requests.
- XSRF protection — Automatic XSRF header support for applications that require it.
- Multiple response formats — Work with JSON, text, binary data, or streaming responses.
- Configurable retries — Automatically retry failed requests with configurable backoff behavior.
- Redirect handling — Follow HTTP redirects with configurable behavior.
- Proxy support — Route requests through HTTP and other supported proxy configurations.
- Connection pooling — Efficiently reuse network connections across requests.
- Unix domain sockets — Communicate with services exposed through Unix sockets.
- Mock adapter — Test HTTP-based applications without performing real network requests.
- Fully typed — Includes type information for modern Python development environments.
Installation
pip install atomhttp
For development and testing:
pip install "atomhttp[test]"
Quick Start
Basic Request
from atomhttp import AtomHTTP
client = AtomHTTP(base_url="https://api.example.com")
response = client.get("/users/1")
print(response.status)
print(response.data)
One-Off Requests
For simple requests, a client instance is not required:
import atomhttp
response = atomhttp.get("https://api.example.com/users/1")
print(response.data)
HTTP Methods
AtomHTTP provides a consistent interface for common HTTP methods:
response = client.get("/users")
response = client.post("/users", data={
"name": "Ada"
})
response = client.put("/users/1", data={
"name": "Ada Lovelace"
})
response = client.patch("/users/1", data={
"name": "Ada"
})
response = client.delete("/users/1")
Request Configuration
Requests can be configured with headers, query parameters, request data, and other options:
response = client.get(
"/users",
params={
"page": 1,
"limit": 20,
},
headers={
"Authorization": "Bearer <token>",
},
)
JSON Requests
Send JSON payloads directly:
response = client.post(
"/users",
json={
"name": "Ada Lovelace",
"email": "ada@example.com",
},
)
The response can then be accessed through the unified response interface:
print(response.status)
print(response.data)
Asynchronous API
Asynchronous support is available when needed:
import asyncio
from atomhttp import AsyncAtomHTTP
async def main():
async with AsyncAtomHTTP(
base_url="https://api.example.com"
) as client:
response = await client.get("/users/1")
print(response.data)
asyncio.run(main())
The asynchronous API follows the same overall interface, making it easy to switch between synchronous and asynchronous applications.
Concurrent Requests
Run multiple requests concurrently with a single call.
Synchronous
responses = client.all([
lambda: client.get("/users/1"),
lambda: client.get("/users/2"),
lambda: client.get("/users/3"),
])
for response in responses:
print(response.data)
Asynchronous
responses = await async_client.all([
async_client.get("/users/1"),
async_client.get("/users/2"),
async_client.get("/users/3"),
])
for response in responses:
print(response.data)
File Uploads
Uploading files is straightforward:
from atomhttp import FormData
form = FormData()
form.append("username", "ada")
form.append(
"avatar",
open("photo.jpg", "rb"),
filename="photo.jpg",
)
response = client.post(
"/profile",
data=form,
)
Upload & Download Progress
Track transfer progress using callbacks:
def on_progress(current, total):
if total:
percentage = (current / total) * 100
print(f"{percentage:.1f}%")
response = client.get(
"/large-file.zip",
on_download_progress=on_progress,
)
Progress callbacks are invoked incrementally during the transfer, making them suitable for CLI applications, desktop applications, and other interfaces that need real-time progress reporting.
Interceptors
Intercept requests before they are sent:
def add_auth(config):
config.headers["Authorization"] = f"Bearer {get_token()}"
return config
client.interceptors.request.use(add_auth)
Response interceptors can be used for centralized response processing:
def handle_response(response):
return response
client.interceptors.response.use(handle_response)
Interceptors are useful for authentication, logging, request transformation, error handling, and application-wide policies.
Cookies
Cookie handling is built into the client:
client = AtomHTTP(
base_url="https://example.com"
)
client.get("/login")
response = client.get("/dashboard")
Cookies received from the server can automatically be reused by subsequent requests made through the same client.
Retries
Configure automatic retries for transient failures:
client = AtomHTTP(
base_url="https://api.example.com",
retry_config={
"total": 3,
"backoff_factor": 0.5,
},
)
Retry behavior can be adjusted according to the requirements of your application.
Streaming Responses
Large responses can be consumed as a stream instead of loading the entire payload into memory:
response = client.get(
"/large-file.zip",
response_type="stream",
)
for chunk in response.iter_bytes():
process(chunk)
This is useful for large downloads, media files, data processing pipelines, and other memory-sensitive workloads.
Unix Domain Sockets
AtomHTTP can communicate with services exposed through Unix domain sockets:
client = AtomHTTP(
base_url="http+unix://%2Fvar%2Frun%2Fdocker.sock"
)
response = client.get("/version")
print(response.data)
Mocking & Testing
Use the mock adapter to test HTTP interactions without making real network requests:
from atomhttp import AtomHTTP, MockAdapter
mock = MockAdapter()
mock.on(
"GET",
"/users/1",
status=200,
data={
"id": 1,
"name": "Ada",
},
)
client = AtomHTTP(adapter=mock)
response = client.get("/users/1")
assert response.status == 200
assert response.data["name"] == "Ada"
This makes it possible to test API integrations deterministically and independently from external services.
Response Handling
Responses expose a consistent interface:
response.status
response.headers
response.data
response.text
Depending on the configured response type, binary and streaming data can also be accessed through the response object.
Client Configuration
A reusable client can be configured once and shared throughout an application:
client = AtomHTTP(
base_url="https://api.example.com",
headers={
"Accept": "application/json",
},
)
This is particularly useful when working with APIs that share authentication, headers, retry policies, or other common configuration.
Error Handling
HTTP and transport errors can be handled explicitly:
try:
response = client.get("/users/1")
except Exception as exc:
print(f"Request failed: {exc}")
For production applications, errors can be handled centrally through interceptors or application-specific exception handling.
Requirements
- Python 3.8+
Testing
Install the development dependencies:
pip install -e ".[test]"
Run the test suite:
pytest
Type Checking
AtomHTTP includes type information and is designed to work with modern Python type-checking and IDE tooling.
License
See the LICENSE file for licensing information.
Contributing
Contributions are welcome.
Before submitting a pull request:
- Add or update tests for your changes.
- Ensure the test suite passes.
- Keep public APIs backward-compatible whenever possible.
- Keep changes focused and well documented.
Documentation
For complete API documentation, examples, configuration options, and advanced usage, visit the project documentation.
AtomHTTP — a clean, powerful HTTP client for Python.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file atomhttp-2.0.0.tar.gz.
File metadata
- Download URL: atomhttp-2.0.0.tar.gz
- Upload date:
- Size: 29.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d1d8659bb00360bf7f0b3d5dcc496a570c13b3dd7328c35e2b04cff40b8feb5e
|
|
| MD5 |
b7e08eda9cb388a3b2e43867931ce03e
|
|
| BLAKE2b-256 |
136d6aed9602e7be9cea482e973788b15c0f7bb92104aef0cf45af0eedfe35b1
|
File details
Details for the file atomhttp-2.0.0-py3-none-any.whl.
File metadata
- Download URL: atomhttp-2.0.0-py3-none-any.whl
- Upload date:
- Size: 30.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
27bec7b7ecd747c090c08312912e97399d9a3fb9fe59c58c2756b4eb3f8c4645
|
|
| MD5 |
57f3bad21cc9b11042ff8f75e91a8dc3
|
|
| BLAKE2b-256 |
7fa6e1d39696cffbc3d0d0ad8fe0b8f9167875fc63465dad9a3a85cc6d8961ba
|