Core API Reference
ParallelBatchProcessor
async_batch_llm.ParallelBatchProcessor
ParallelBatchProcessor(max_workers: int | None = None, post_processor: PostProcessorFunc[TOutput, TContext] | None = None, timeout_per_item: float | None = None, rate_limit_cooldown: float | None = None, config: ProcessorConfig | None = None, error_classifier: ErrorClassifier | None = None, rate_limit_strategy: RateLimitStrategy | None = None, middlewares: list[Middleware[TInput, TOutput, TContext]] | None = None, observers: list[ProcessorObserver] | None = None, progress_callback: ProgressCallbackFunc | None = None)
Bases: BatchProcessor[TInput, TOutput, TContext], Generic[TInput, TOutput, TContext]
Batch processor that executes items in parallel as individual agent calls.
This refactored version uses: - Pluggable error classification (provider-agnostic) - Pluggable rate limit strategies - Middleware pipeline for extensibility - Observer pattern for monitoring - Configuration objects for easier setup
Initialize the parallel batch processor.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
max_workers
|
int | None
|
Maximum concurrent workers (deprecated, use config) |
None
|
post_processor
|
PostProcessorFunc[TOutput, TContext] | None
|
Optional async function called after each successful item |
None
|
timeout_per_item
|
float | None
|
Timeout per item in seconds (deprecated, use config) |
None
|
rate_limit_cooldown
|
float | None
|
Cooldown duration (deprecated, use config) |
None
|
config
|
ProcessorConfig | None
|
Processor configuration object (recommended) |
None
|
error_classifier
|
ErrorClassifier | None
|
Strategy for classifying errors (default: DefaultErrorClassifier) |
None
|
rate_limit_strategy
|
RateLimitStrategy | None
|
Strategy for handling rate limits |
None
|
middlewares
|
list[Middleware[TInput, TOutput, TContext]] | None
|
List of middleware to apply |
None
|
observers
|
list[ProcessorObserver] | None
|
List of observers for events |
None
|
progress_callback
|
ProgressCallbackFunc | None
|
Optional callback(completed, total, current_item_id) for progress updates |
None
|
Source code in src/async_batch_llm/parallel.py
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 | |
__aexit__
async
__aexit__(exc_type: type[BaseException] | None, exc_val: BaseException | None, exc_tb: TracebackType | None) -> bool
Context manager exit - ensures cleanup of strategies and resources.
Calls cleanup() on all prepared strategies, then delegates to parent cleanup.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
exc_type
|
type[BaseException] | None
|
Exception type (if any exception occurred) |
required |
exc_val
|
BaseException | None
|
Exception value (if any exception occurred) |
required |
exc_tb
|
TracebackType | None
|
Exception traceback (if any exception occurred) |
required |
Returns:
| Type | Description |
|---|---|
bool
|
False to indicate exceptions should not be suppressed |
Source code in src/async_batch_llm/parallel.py
add_work
async
Queue a work item, recording its strategy's classifier recommendation.
Extends the base queueing with the bookkeeping needed to auto-select an
error classifier at batch start when the caller didn't pass one. A
no-op recommendation (custom strategies returning None) is ignored.
Source code in src/async_batch_llm/parallel.py
get_stats
async
Get processor statistics (thread-safe).
Returns:
| Type | Description |
|---|---|
dict
|
Dictionary containing processing statistics including: |
dict
|
|
dict
|
|
dict
|
|
dict
|
|
dict
|
|
dict
|
|
dict
|
|
Source code in src/async_batch_llm/parallel.py
LLMWorkItem
async_batch_llm.LLMWorkItem
dataclass
LLMWorkItem(item_id: str, strategy: LLMCallStrategy[TOutput], prompt: str = '', context: TContext | None = None)
Bases: Generic[TInput, TOutput, TContext]
Represents a single work item to be processed by an LLM strategy.
Attributes:
| Name | Type | Description |
|---|---|---|
item_id |
str
|
Unique identifier for this work item |
strategy |
LLMCallStrategy[TOutput]
|
LLM call strategy that encapsulates how to make the LLM call |
prompt |
str
|
The prompt/input to pass to the LLM |
context |
TContext | None
|
Optional context data passed through to results/post-processor |
__post_init__
Validate work item fields.
Source code in src/async_batch_llm/base.py
WorkItemResult
async_batch_llm.WorkItemResult
dataclass
WorkItemResult(item_id: str, success: bool, output: TOutput | None = None, error: str | None = None, context: TContext | None = None, token_usage: TokenUsage = (lambda: {'input_tokens': 0, 'output_tokens': 0, 'total_tokens': 0})(), metadata: dict[str, Any] | None = None, gemini_safety_ratings: dict[str, str] | None = None, exception: Exception | None = None)
Bases: ProviderOutputViews, Generic[TOutput, TContext]
Result of processing a single work item.
Attributes:
| Name | Type | Description |
|---|---|---|
item_id |
str
|
ID of the work item |
success |
bool
|
Whether processing succeeded |
output |
TOutput | None
|
Agent output if successful, None if failed |
error |
str | None
|
Error message if failed, None if successful |
context |
TContext | None
|
Context data from the work item |
token_usage |
TokenUsage
|
Token usage stats (input_tokens, output_tokens, total_tokens) |
metadata |
dict[str, Any] | None
|
Provider-specific metadata returned alongside the response —
e.g. |
gemini_safety_ratings |
dict[str, str] | None
|
Deprecated. Use |
exception |
Exception | None
|
The originating exception for a failed result, when one was
raised (all retries exhausted, or a permanent non-retryable error).
|
__post_init__
Backfill gemini_safety_ratings from metadata['safety_ratings']
for backward compatibility. Once gemini_safety_ratings is removed,
this method goes away. (Reads/writes go through __dict__ directly
so the framework itself never triggers the deprecation warning.)
Source code in src/async_batch_llm/base.py
ProcessorConfig
async_batch_llm.ProcessorConfig
dataclass
ProcessorConfig(max_workers: int = 5, timeout_per_item: float = 120.0, post_processor_timeout: float = 90.0, concurrent_post_processing: bool = False, retry: RetryConfig = RetryConfig(), rate_limit: RateLimitConfig = RateLimitConfig(), max_requests_per_minute: float | None = None, progress_interval: int = 10, progress_callback_timeout: float | None = 5.0, enable_detailed_logging: bool = False, max_queue_size: int = 0, dry_run: bool = False)
Complete configuration for batch processor.
__post_init__
validate
Validate complete configuration.
Source code in src/async_batch_llm/core/config.py
BatchResult
async_batch_llm.BatchResult
dataclass
Bases: Generic[TOutput, TContext]
Result of processing a batch of work items.
Attributes:
| Name | Type | Description |
|---|---|---|
results |
list[WorkItemResult[TOutput, TContext]]
|
Individual work item results, in completion order — the
order items finished, which (with parallel workers, retries, and
rate-limit cooldowns) is generally NOT the order they were added.
Use :meth: |
total_items |
int
|
Total number of items in the batch |
succeeded |
int
|
Number of successful items |
failed |
int
|
Number of failed items |
total_input_tokens |
int
|
Sum of input tokens across all items |
total_output_tokens |
int
|
Sum of output tokens across all items |
total_cached_tokens |
int
|
Sum of cached input tokens across all items (v0.2.0) |
failures
property
The failed results only, in completion order.
successes
property
The successful results only, in completion order.
__post_init__
Calculate summary statistics from results.
Source code in src/async_batch_llm/base.py
by_id
Map item_id -> result for direct lookup.
Results are ordered by completion, so use this when you need to align
outputs back to specific inputs. If two results somehow share an
item_id, the later-completed one wins.
Source code in src/async_batch_llm/base.py
cache_hit_rate
Calculate cache hit rate as percentage of input tokens that were cached.
Returns:
| Type | Description |
|---|---|
float
|
Percentage (0.0 to 100.0) of input tokens served from cache |
Source code in src/async_batch_llm/base.py
effective_input_tokens
Estimate billable input tokens after the cache discount.
cached_token_rate is the fraction of the normal input-token price
you pay for tokens served from cache. For example, Gemini charges
10% of the normal price (rate = 0.10), so 1000 cached tokens cost
the same as 100 uncached tokens.
Use the named constants on :class:CachedTokenRates to avoid
hardcoding magic numbers:
.. code-block:: python
result.effective_input_tokens(CachedTokenRates.OPENAI)
result.effective_input_tokens(CachedTokenRates.GEMINI)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cached_token_rate
|
float | None
|
Fraction (0.0–1.0) of the normal input price
paid for cached tokens. When omitted ( |
None
|
Returns:
| Type | Description |
|---|---|
int
|
Effective input tokens billed. The discount is computed by |
int
|
truncating |
int
|
|
int
|
rounded up when the discount would have a fractional |
int
|
part — a deliberately conservative choice for cost reporting |
int
|
(your real bill is at most this number, never more). |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in src/async_batch_llm/base.py
estimated_cost
estimated_cost(input_per_mtok: float, output_per_mtok: float, cached_token_rate: float | None = None) -> float
Estimate total spend from per-million-token prices.
Applies the cache discount to input tokens via
:meth:effective_input_tokens, so cached tokens are billed at their
reduced rate.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
input_per_mtok
|
float
|
Price per 1,000,000 input tokens (in your currency). |
required |
output_per_mtok
|
float
|
Price per 1,000,000 output tokens. |
required |
cached_token_rate
|
float | None
|
Fraction of the normal input price paid for
cached tokens (see :class: |
None
|
Returns:
| Type | Description |
|---|---|
float
|
Estimated total cost: ``effective_input / 1e6 * input_per_mtok + |
float
|
output / 1e6 * output_per_mtok``. |
Source code in src/async_batch_llm/base.py
Grounding
async_batch_llm.Grounding
dataclass
Grounding(sources: list[GroundingSource] = list(), queries: list[str] = list(), supports: list[dict[str, Any]] = list())
Web-grounding data from a grounded call (e.g. Gemini google_search).
Attributes:
| Name | Type | Description |
|---|---|---|
sources |
list[GroundingSource]
|
The web sources the answer was grounded in. |
queries |
list[str]
|
Search queries the model issued ( |
supports |
list[dict[str, Any]]
|
Answer-span → source-index links, as plain dicts
( |
from_metadata
classmethod
Parse a metadata['grounding'] dict; lenient, never raises.
Source code in src/async_batch_llm/provider_output.py
GroundingSource
async_batch_llm.GroundingSource
dataclass
One web source backing a grounded response.
Attributes:
| Name | Type | Description |
|---|---|---|
uri |
str
|
Source URL (always present; entries without one are dropped). |
title |
str | None
|
Human-readable page title, when the provider supplied one. |
snippet |
str | None
|
Excerpt from the source, when the provider supplied one. |
from_metadata
classmethod
Parse one metadata['grounding']['sources'] entry; lenient, never raises.
Source code in src/async_batch_llm/provider_output.py
ToolCall
async_batch_llm.ToolCall
dataclass
One tool/function call the model requested. Visibility only — the framework never executes tools; feed these to your own dispatch loop.
Attributes:
| Name | Type | Description |
|---|---|---|
id |
str | None
|
Provider call id, when supplied. |
name |
str
|
Tool/function name (always present; entries without one are dropped). |
arguments |
str
|
The raw JSON-string arguments, deliberately unparsed —
parse with |
from_metadata
classmethod
Parse one metadata['tool_calls'] entry; lenient, never raises.