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

ParameterTypeDefaultDescription
urlstrRequiredThe endpoint URL
paramsdict{}Query parameters for filtering, pagination, sorting
headersdict{}Custom HTTP headers
response_typestr"json"Response format: json, text, blob, arraybuffer, stream
timeoutint/floatNoneOverride client timeout

Returns

Response Response object containing data, status, headers, config

Example

1
2
3
4
5
6
7
8
9
# 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

ParameterTypeDefaultDescription
urlstrRequiredThe endpoint URL
dataAnyNoneRequest body (dict, FormData, bytes, str)
headersdict{}Custom HTTP headers (Content-Type auto-detected)
response_typestr"json"Response format
on_upload_progressCallableNoneProgress callback for uploads

Returns

Response Response object with created resource data

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 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

ParameterTypeDefaultDescription
urlstrRequiredThe endpoint URL with resource ID
datadictRequiredComplete resource data
headersdict{}Custom HTTP headers

Returns

Response Response object with updated resource data

Example

1
2
3
4
5
6
7
# 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

ParameterTypeDefaultDescription
urlstrRequiredThe endpoint URL with resource ID
datadictRequiredFields to update (partial data)
headersdict{}Custom HTTP headers

Returns

Response Response object with updated resource data

Example

1
2
3
4
5
6
7
8
9
10
# 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

ParameterTypeDefaultDescription
urlstrRequiredThe endpoint URL with resource ID
paramsdict{}Query parameters for batch delete
headersdict{}Custom HTTP headers

Returns

Response Response object (status 204 on success)

Example

1
2
3
4
5
6
7
8
9
10
# 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

ParameterTypeDefaultDescription
urlstrRequiredThe endpoint URL
headersdict{}Custom HTTP headers

Returns

Response Response object with headers but empty body

Example

1
2
3
4
5
6
7
8
9
# 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

ParameterTypeDefaultDescription
urlstrRequiredThe endpoint URL
headersdict{}Custom HTTP headers

Returns

Response Response with Allow header listing supported methods

Example

1
2
3
4
5
6
7
8
9
# 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

ParameterTypeDefaultDescription
configdictRequiredFull request configuration dictionary
config.methodstrRequiredHTTP method (GET, POST, etc.)
config.urlstrRequiredRequest URL
config.dataAnyNoneRequest body
config.paramsdict{}Query parameters
config.headersdict{}Custom headers
config.timeoutintNoneRequest timeout

Returns

Response Response object

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 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:

PropertyDescriptionTypeExample
response.dataParsed response bodydict, list, str, bytesresponse.data['id']
response.statusHTTP status codeintresponse.status == 200
response.status_textHTTP status messagestrresponse.status_text
response.headersResponse headersdictresponse.headers['Content-Type']
response.configOriginal request configRequestConfigresponse.config.url
response.okSuccess indicator (200-299)boolif response.ok: ...
1
2
3
4
5
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

json

Parses as dict/list

text

Returns raw text → str

blob

Returns binary → bytes

stream

Async iterator for large data

Client Configuration

Configure your client with defaults that apply to every request:

OptionTypeDefaultDescription
baseURLstr""Base URL prepended to relative paths
timeoutint/float30Request timeout in seconds
headersdict{}Default headers sent with every request
maxRedirectsint5Maximum number of redirects to follow
responseTypestr"json"Response format: json, text, blob, arraybuffer, stream
keepAliveboolTrueEnable HTTP keep-alive connections
verifyboolTrueEnable SSL certificate verification for HTTPS requests
retryConfigdictNoneRetry settings for transient failures: max_retries, backoff_factor, status_forcelist
decompressboolTrueAutomatically decompress gzip/deflate responses
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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.

1
2
3
4
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

Authorization

Bearer token or Basic auth

Content-Type

Media type of request body

Accept

Expected response media type

User-Agent

Client identifier

Query Parameter Best Practices

  • Use params for 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 TypeDescriptionError Code
AtomHTTPRequestErrorBad request (4xx) or malformed requestERR_BAD_REQUEST
AtomHTTPNetworkErrorNetwork connectivity issues, DNS errorsERR_NETWORK
AtomHTTPTimeoutErrorRequest exceeded timeout limitECONNABORTED
1
2
3
4
5
6
7
8
9
10
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_REQUEST

Error Handling Best Practices

  • Catch specific error types before generic Exception
  • Use error.code for programmatic handling
  • Check error.response.data for server error details
  • Implement retry logic for timeout and network errors