Core API
Essential HTTP methods and configuration for everyday use
HTTP Methods
AtomHTTP supports all standard HTTP methods with intuitive async interfaces. Each method returns a Response object containing the parsed response body, status code, headers, and original request configuration.
GET Request
Retrieve data from a server. GET requests should only retrieve data and should not have any other effect.
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
| url | str | Required | The endpoint URL |
| params | dict | {} | Query parameters for filtering, pagination, sorting |
| headers | dict | {} | Custom HTTP headers |
| response_type | str | "json" | Response format: json, text, blob, arraybuffer, stream |
| timeout | int/float | None | Override client timeout |
Returns
Response — Response object containing data, status, headers, configExample
# Basic GET request
response = await client.get('https://api.example.com/users')
# GET with query parameters
response = await client.get('/users', params={'page': 1, 'limit': 10, 'sort': 'desc'})
print(response.data)
# GET with custom headers
response = await client.get('/protected', headers={'Authorization': 'Bearer token123'})POST Request
Send data to create a new resource. Accepts JSON, FormData, URL-encoded data, or raw bytes.
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
| url | str | Required | The endpoint URL |
| data | Any | None | Request body (dict, FormData, bytes, str) |
| headers | dict | {} | Custom HTTP headers (Content-Type auto-detected) |
| response_type | str | "json" | Response format |
| on_upload_progress | Callable | None | Progress callback for uploads |
Returns
Response — Response object with created resource dataExample
# POST with JSON data
user_data = {'name': 'John Doe', 'email': 'john@example.com'}
response = await client.post('/users', data=user_data)
print(f"Created ID: {response.data['id']}")
# POST with FormData (file upload)
form = AtomHTTP.FormData()
form.append('name', 'John Doe')
form.append('avatar', open('photo.jpg', 'rb'), filename='photo.jpg')
response = await client.post('/users', data=form)
# POST with progress tracking
def on_progress(loaded, total):
print(f"Uploaded: {loaded}/{total} bytes")
response = await client.post('/upload', data=large_file, on_upload_progress=on_progress)PUT Request
Completely replace an existing resource. Requires the complete resource data.
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
| url | str | Required | The endpoint URL with resource ID |
| data | dict | Required | Complete resource data |
| headers | dict | {} | Custom HTTP headers |
Returns
Response — Response object with updated resource dataExample
# Full resource replacement
update_data = {'id': 1, 'name': 'Jane Doe', 'email': 'jane@example.com', 'role': 'admin'}
response = await client.put('/users/1', data=update_data)
# Conditional update
response = await client.put('/users/1', data=update_data,
headers={'If-Unmodified-Since': 'Wed, 21 Oct 2024 07:28:00 GMT'})PATCH Request
Partially update an existing resource. Only send the fields that need to be changed.
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
| url | str | Required | The endpoint URL with resource ID |
| data | dict | Required | Fields to update (partial data) |
| headers | dict | {} | Custom HTTP headers |
Returns
Response — Response object with updated resource dataExample
# Partial update
response = await client.patch('/users/1', data={'email': 'newemail@example.com'})
# Update multiple fields
response = await client.patch('/users/1', data={'email': 'newemail@example.com', 'role': 'editor'})
# JSON Patch operations
response = await client.patch('/users/1', data=[
{'op': 'replace', 'path': '/email', 'value': 'new@example.com'}
])DELETE Request
Remove a resource from the server.
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
| url | str | Required | The endpoint URL with resource ID |
| params | dict | {} | Query parameters for batch delete |
| headers | dict | {} | Custom HTTP headers |
Returns
Response — Response object (status 204 on success)Example
# Delete a single resource
response = await client.delete('/users/1')
if response.status == 204:
print("User deleted successfully")
# Batch delete
response = await client.delete('/users', params={'ids': '1,2,3'})
# Conditional delete
response = await client.delete('/users/1', headers={'If-Match': 'etag123'})HEAD Request
Retrieve headers only, without the response body.
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
| url | str | Required | The endpoint URL |
| headers | dict | {} | Custom HTTP headers |
Returns
Response — Response object with headers but empty bodyExample
# Check if resource exists
response = await client.head('/large-file.pdf')
print(f"Size: {response.headers.get('Content-Length')} bytes")
print(f"Type: {response.headers.get('Content-Type')}")
print(f"Modified: {response.headers.get('Last-Modified')}")
# Check API health
response = await client.head('/health')
print(f"Status: {'healthy' if response.ok else 'unhealthy'}")OPTIONS Request
Discover which HTTP methods are supported by a resource.
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
| url | str | Required | The endpoint URL |
| headers | dict | {} | Custom HTTP headers |
Returns
Response — Response with Allow header listing supported methodsExample
# Discover allowed methods
response = await client.options('/users/1')
print(f"Allowed: {response.headers.get('Allow', '')}")
# CORS preflight
response = await client.options('/api/data', headers={
'Origin': 'https://myapp.com',
'Access-Control-Request-Method': 'POST'
})Generic Request Method
Unified request method for maximum flexibility.
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
| config | dict | Required | Full request configuration dictionary |
| config.method | str | Required | HTTP method (GET, POST, etc.) |
| config.url | str | Required | Request URL |
| config.data | Any | None | Request body |
| config.params | dict | {} | Query parameters |
| config.headers | dict | {} | Custom headers |
| config.timeout | int | None | Request timeout |
Returns
Response — Response objectExample
# Full control over request configuration
response = await client.request({
'method': 'POST',
'url': '/api/data',
'data': {'key': 'value'},
'headers': {'X-Custom': 'header'},
'params': {'version': 'v2'},
'timeout': 30,
'maxRedirects': 0,
'responseType': 'text'
})
# Dynamic method selection
method = 'DELETE' if condition else 'PUT'
response = await client.request({'method': method, 'url': '/resource/1'})Response Object
Every request returns a Response object with the following properties:
| Property | Description | Type | Example |
|---|---|---|---|
| response.data | Parsed response body | dict, list, str, bytes | response.data['id'] |
| response.status | HTTP status code | int | response.status == 200 |
| response.status_text | HTTP status message | str | response.status_text |
| response.headers | Response headers | dict | response.headers['Content-Type'] |
| response.config | Original request config | RequestConfig | response.config.url |
| response.ok | Success indicator (200-299) | bool | if response.ok: ... |
response = await client.get('https://httpbin.org/get')
print(f"Status: {response.status} {response.status_text}")
print(f"Content-Type: {response.headers.get('Content-Type')}")
print(f"Body: {response.data}")
print(f"URL: {response.config.url}")Response Types
jsonParses as dict/list
textReturns raw text → str
blobReturns binary → bytes
streamAsync iterator for large data
Client Configuration
Configure your client with defaults that apply to every request:
| Option | Type | Default | Description |
|---|---|---|---|
| baseURL | str | "" | Base URL prepended to relative paths |
| timeout | int/float | 30 | Request timeout in seconds |
| headers | dict | {} | Default headers sent with every request |
| maxRedirects | int | 5 | Maximum number of redirects to follow |
| responseType | str | "json" | Response format: json, text, blob, arraybuffer, stream |
| keepAlive | bool | True | Enable HTTP keep-alive connections |
| verify | bool | True | Enable SSL certificate verification for HTTPS requests |
| retryConfig | dict | None | Retry settings for transient failures: max_retries, backoff_factor, status_forcelist |
| decompress | bool | True | Automatically decompress gzip/deflate responses |
client = AtomHTTP({
'baseURL': 'https://api.example.com',
'timeout': 15,
'headers': {'X-API-Key': 'your-api-key', 'Accept': 'application/json'},
'maxRedirects': 3,
'responseType': 'json',
'keepAlive': True,
'verify': True,
'retryConfig': {
'max_retries': 3,
'backoff_factor': 0.3,
'status_forcelist': [408, 429, 500, 502, 503, 504]
}
})
# All requests use these defaults
response = await client.get('/users')
# Override for specific request
response = await client.get('/slow', timeout=60)Configuration Inheritance
Client-level defaults are merged with request-level options. Headers are deeply merged (request headers override client headers), while other options are replaced entirely.
Headers & Query Parameters
Add custom headers for authentication and metadata. Use query parameters for filtering and pagination.
response = await client.get('https://httpbin.org/get',
params={'search': 'python', 'page': 2, 'limit': 20},
headers={'Authorization': 'Bearer token123', 'X-Custom-Header': 'value'}
)Common Headers
AuthorizationBearer token or Basic auth
Content-TypeMedia type of request body
AcceptExpected response media type
User-AgentClient identifier
Query Parameter Best Practices
- Use
paramsfor GET, DELETE requests - Avoid sensitive data in query parameters (they appear in logs)
- Use arrays for multi-value parameters
- Auto URL-encoded — no manual encoding needed
Error Types
AtomHTTP provides comprehensive error types with standardized error codes:
| Error Type | Description | Error Code |
|---|---|---|
| AtomHTTPRequestError | Bad request (4xx) or malformed request | ERR_BAD_REQUEST |
| AtomHTTPNetworkError | Network connectivity issues, DNS errors | ERR_NETWORK |
| AtomHTTPTimeoutError | Request exceeded timeout limit | ECONNABORTED |
from atomhttp.errors import AtomHTTPTimeoutError, AtomHTTPNetworkError, AtomHTTPRequestError
try:
response = await client.get('https://api.example.com/data', timeout=5)
except AtomHTTPTimeoutError as e:
print(f"Timeout: {e.code}") # ECONNABORTED
except AtomHTTPNetworkError as e:
print(f"Network error: {e.code}") # ERR_NETWORK
except AtomHTTPRequestError as e:
print(f"Request failed: {e.code} - Status {e.response.status}") # ERR_BAD_REQUESTError Handling Best Practices
- Catch specific error types before generic Exception
- Use
error.codefor programmatic handling - Check
error.response.datafor server error details - Implement retry logic for timeout and network errors