Batch processing for AI models with cost tracking and state persistence
Project description
Batchata
Unified API for AI Batch requests with cost tracking, Pydantic responses, citation mapping and parallel execution.
Why Batchata?
- Native batch processing (50% cost savings via provider APIs)
- Set $ cost limits for batch requests
- State persistence for network interruption recovery
- Structured output with Pydantic models
- Citation extraction and field mapping (supported only by anthropic atm)
Installation
pip
pip install batchata
uv
uv add batchata
Quick Start
from batchata import Batch
# Simple batch processing
batch = Batch(state_file="./state.json", results_dir="./output", max_concurrent=10)
.defaults(model="claude-sonnet-4-20250514")
.add_cost_limit(usd=15)
for file in files:
batch.add_job(file=file, prompt="Summarize")
run = batch.run(wait=True)
results = run.results() # Dict[job_id, JobResult]
API
Batch
Batch(
state_file: str,
results_dir: str,
max_concurrent: int = 10,
items_per_batch: int = 10,
reuse_state: bool = True,
save_raw_responses: Optional[bool] = None
)
state_file: Path to save batch state for recovery (in case of network interruption)results_dir: Directory to store individual job resultsmax_concurrent: Maximum parallel batch requests (default: 10)items_per_batch: Number of jobs per provider batch (affects cost tracking accuracy, default: 10)reuse_state: Whether to resume from existing state file and delete previous results_dir file results (default: True)save_raw_responses: Whether to save raw API responses in the results dir (default: True if results_dir is set)
Methods:
.defaults(**kwargs)
Set default parameters for all jobs. Common parameters:
model: Model name (e.g., "claude-sonnet-4-20250514", "gpt-4")temperature: Sampling temperature 0.0-1.0 (default: 0.7)max_tokens: Maximum tokens to generate (default: 1000)
.add_cost_limit(usd: float)
Set maximum spend limit. Batch will stop accepting new jobs when limit is reached.
.set_verbosity(level: str)
Set logging verbosity level. Useful for production environments.
- Levels: "debug", "info" (default), "warning", "error"
- Example:
batch.set_verbosity("error")for production
.add_job(...)
Add a job to the batch. Parameters:
messages: Chat messages (list of dicts with "role" and "content")file: Path to file for file-based input (supports string paths, Path objects, and PDF files)prompt: Prompt to use with file inputmodel: Override default modeltemperature: Override default temperature (0.0-1.0)max_tokens: Override default max tokensresponse_model: Pydantic model for structured outputenable_citations: Extract citations from response (default: False)
Note: Provide either messages OR file+prompt, not both.
.run(wait: bool = False, on_progress: Callable = None)
Execute the batch. Returns a BatchRun object.
wait=True: Block until all jobs completewait=False: Return immediately, process in backgroundon_progress: Optional progress callback function
BatchRun
Object returned by batch.run():
.status(print_status: bool = False)- Get current batch status.results()- Get completed results as Dict[str, JobResult].wait(timeout: float = None)- Wait for batch completion.on_progress(callback, interval=3.0)- Set progress monitoring callback.shutdown(wait_for_active: bool = True)- Gracefully shutdown
The progress callback receives a dict with:
batch_id: Current batch identifiertotal: Total number of jobspending: Jobs waiting to startactive: Jobs currently processingcompleted: Successfully completed jobsfailed: Failed jobscost_usd: Current total costcost_limit_usd: Cost limit (if set)is_complete: Whether batch is finishedbatches_completed: Number of completed batchesbatches_total: Total number of batchesbatches_pending: Number of pending batchesitems_per_batch: Items per batch setting
JobResult
job_id: Unique identifierraw_response: Raw text responseparsed_response: Structured data (if response_model used)citations: List of Citation objects (if enabled)citation_mappings: Dict[str, List[Citation]] - Maps field names to relevant citations (not 100% accurate, only with response_model)input_tokens: Input token countoutput_tokens: Output token countcost_usd: Cost for this joberror: Error message (if failed)is_success: Property that returns True if job completed successfullytotal_tokens: Property that returns total tokens used (input + output)
Citation
Each Citation object contains:
text: The cited textsource: Source identifier (e.g., file name)page: Page number if applicable (for PDFs)metadata: Additional metadata dict
File Structure
./results/
├── job-abc123.json
├── job-def456.json
└── job-ghi789.json
./batch_state.json # Batch state
Configuration
Set your API keys as environment variables:
export ANTHROPIC_API_KEY="your-key"
export OPENAI_API_KEY="your-key"
export GOOGLE_API_KEY="your-key"
You can also use a .env file in your project root (requires python-dotenv):
from dotenv import load_dotenv
load_dotenv()
from batchata import Batch
# Your API keys will now be loaded from .env
Limitations
- Parallel execution not implemented yet.
- Field/citation mapping is heuristic, which means it isn't perfect.
- Citation mapping only works with flat Pydantic models (no nested BaseModel fields).
- Right now only Anthropic Batch requests are supported.
- Cost tracking is not precise as the actual usage is only known after the batch is complete, try setting
items_per_batchto a lower value for more accurate cost tracking.
License
MIT License - see LICENSE file for details.
Project details
Release history Release notifications | RSS feed
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 batchata-0.3.0.tar.gz.
File metadata
- Download URL: batchata-0.3.0.tar.gz
- Upload date:
- Size: 121.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b9b90643a72cae30fd3d9e0adad34eb0c68309e8ac21d0fd0d5ae18797cf2e38
|
|
| MD5 |
1e389ba145af208f52efa6fd2f1415e9
|
|
| BLAKE2b-256 |
25da4ebb6d0de53b37e792bb0bab0dcffb3a8fb5c5deec94e7e3dded2e3e2ceb
|
Provenance
The following attestation bundles were made for batchata-0.3.0.tar.gz:
Publisher:
publish.yml on agamm/batchata
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
batchata-0.3.0.tar.gz -
Subject digest:
b9b90643a72cae30fd3d9e0adad34eb0c68309e8ac21d0fd0d5ae18797cf2e38 - Sigstore transparency entry: 274082763
- Sigstore integration time:
-
Permalink:
agamm/batchata@57f3689c4d767943039c70b30a4bb440a6301630 -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/agamm
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@57f3689c4d767943039c70b30a4bb440a6301630 -
Trigger Event:
release
-
Statement type:
File details
Details for the file batchata-0.3.0-py3-none-any.whl.
File metadata
- Download URL: batchata-0.3.0-py3-none-any.whl
- Upload date:
- Size: 38.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
82deadd889f0d655f334afc5c58bb7c473c0de075a49d6d5d39ec48921240661
|
|
| MD5 |
b43e4e22af0807d7241c46a0973fad61
|
|
| BLAKE2b-256 |
96e478ad7f091cc2ab172dfd84f192a2b8f5da38287bd32a48514c822b8108de
|
Provenance
The following attestation bundles were made for batchata-0.3.0-py3-none-any.whl:
Publisher:
publish.yml on agamm/batchata
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
batchata-0.3.0-py3-none-any.whl -
Subject digest:
82deadd889f0d655f334afc5c58bb7c473c0de075a49d6d5d39ec48921240661 - Sigstore transparency entry: 274082773
- Sigstore integration time:
-
Permalink:
agamm/batchata@57f3689c4d767943039c70b30a4bb440a6301630 -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/agamm
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@57f3689c4d767943039c70b30a4bb440a6301630 -
Trigger Event:
release
-
Statement type: