ExLLM.Adapters.Shared.HTTPClient (ex_llm v0.5.0)
View SourceShared HTTP client utilities for ExLLM adapters.
Provides common HTTP functionality including:
- JSON API requests with proper headers
- Server-Sent Events (SSE) streaming support
- Standardized error handling
- Response parsing utilities
This module abstracts common HTTP patterns to reduce duplication across provider adapters.
Summary
Functions
Add custom headers specified by the user.
Add idempotency headers for safe request retries.
Add rate limit headers to the request.
Build provider-specific headers for API requests.
Handle API error responses consistently.
Parse Server-Sent Events from a data buffer.
Make a POST request with JSON body to an API endpoint.
Make a multipart form POST request to upload files.
Make a streaming POST request using Req's into option.
Prepare headers with common defaults.
Make a streaming POST request that returns Server-Sent Events.
Build a standardized User-Agent header for ExLLM.
Functions
Add custom headers specified by the user.
Allows users to add arbitrary headers for specific use cases.
@spec add_idempotency_headers([{String.t(), String.t()}], atom(), keyword()) :: [ {String.t(), String.t()} ]
Add idempotency headers for safe request retries.
Some providers support idempotency keys to prevent duplicate operations.
@spec add_rate_limit_headers([{String.t(), String.t()}], atom(), keyword()) :: [ {String.t(), String.t()} ]
Add rate limit headers to the request.
Some providers support rate limit hints in request headers.
Build provider-specific headers for API requests.
Options
:provider
- Provider name for specific headers:api_key
- API key for authorization:version
- API version header:organization
- Organization ID (OpenAI):project
- Project ID (OpenAI)
Examples
HTTPClient.build_provider_headers(:openai,
api_key: "sk-...",
organization: "org-123"
)
Handle API error responses consistently.
Attempts to parse error details from JSON responses.
Parse Server-Sent Events from a data buffer.
Returns parsed events and remaining buffer.
Examples
{events, new_buffer} = HTTPClient.parse_sse_chunks("data: {"text":"Hi"}\n\n", "")
@spec post_json(String.t(), map(), [{String.t(), String.t()}], keyword()) :: {:ok, map()} | {:error, term()}
Make a POST request with JSON body to an API endpoint.
Options
:timeout
- Request timeout in milliseconds (default: 60s):recv_timeout
- Receive timeout for streaming (default: 5m):stream
- Whether this is a streaming request
Examples
HTTPClient.post_json("https://api.example.com/v1/chat",
%{messages: messages},
[{"Authorization", "Bearer sk-..."}],
timeout: 30_000
)
@spec post_multipart(String.t(), keyword(), [{String.t(), String.t()}], keyword()) :: {:ok, map()} | {:error, term()}
Make a multipart form POST request to upload files.
Parameters
url
- The endpoint URLform_data
- A keyword list of form fields, where file fields are {:file, path}headers
- Request headersopts
- Additional options
Examples
HTTPClient.post_multipart(
"https://api.openai.com/v1/files",
[
purpose: "fine-tune",
file: {:file, "/path/to/file.jsonl"}
],
[{"Authorization", "Bearer sk-..."}]
)
Make a streaming POST request using Req's into option.
This is used by StreamingCoordinator for unified streaming.
Examples
HTTPClient.post_stream(url, body, [
headers: headers,
into: stream_collector_fn
])
Prepare headers with common defaults.
Adds Content-Type and User-Agent if not present.
@spec stream_request( String.t(), map(), [{String.t(), String.t()}], function(), keyword() ) :: {:ok, any()} | {:error, term()}
Make a streaming POST request that returns Server-Sent Events.
The callback function will be called for each chunk received.
Examples
HTTPClient.stream_request(url, body, headers, fn chunk ->
# Process each SSE chunk
IO.puts("Received: " <> chunk)
end)
Build a standardized User-Agent header for ExLLM.