- Spec files
pypi-openai
Describes: pkg:pypi/openai@1.106.x
- Description
- Official Python library for the OpenAI API providing chat completions, embeddings, audio, images, and more
- Author
- tessl
- Last updated
batch-operations.md docs/
1# Batch Operations23Process large volumes of requests efficiently using the batch API for cost-effective bulk operations with 24-hour processing windows.45## Capabilities67### Batch Creation and Management89Create and manage batch processing jobs for efficient bulk API operations.1011```python { .api }12def create(13self,14*,15completion_window: Literal["24h"],16endpoint: Literal["/v1/chat/completions", "/v1/embeddings", "/v1/completions"],17input_file_id: str,18metadata: Optional[Dict[str, str]] | NotGiven = NOT_GIVEN,19extra_headers: Headers | None = None,20extra_query: Query | None = None,21extra_body: Body | None = None,22timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN23) -> Batch: ...2425def list(26self,27*,28after: str | NotGiven = NOT_GIVEN,29limit: int | NotGiven = NOT_GIVEN,30extra_headers: Headers | None = None,31extra_query: Query | None = None,32extra_body: Body | None = None,33timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN34) -> SyncPage[Batch]: ...3536def retrieve(37self,38batch_id: str,39*,40extra_headers: Headers | None = None,41extra_query: Query | None = None,42extra_body: Body | None = None,43timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN44) -> Batch: ...4546def cancel(47self,48batch_id: str,49*,50extra_headers: Headers | None = None,51extra_query: Query | None = None,52extra_body: Body | None = None,53timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN54) -> Batch: ...55```5657Usage examples:5859```python60from openai import OpenAI61import json6263client = OpenAI()6465# Prepare batch requests file66def create_batch_requests_file(requests_data, output_file):67"""Create JSONL file with batch requests"""6869with open(output_file, 'w') as f:70for i, request_data in enumerate(requests_data):71batch_request = {72"custom_id": f"request-{i}",73"method": "POST",74"url": "/v1/chat/completions",75"body": request_data76}77f.write(json.dumps(batch_request) + '\n')7879print(f"Created batch requests file: {output_file}")80return output_file8182# Example chat completion requests83chat_requests = [84{85"model": "gpt-3.5-turbo",86"messages": [{"role": "user", "content": "What is machine learning?"}],87"max_tokens": 10088},89{90"model": "gpt-3.5-turbo",91"messages": [{"role": "user", "content": "Explain neural networks"}],92"max_tokens": 10093},94{95"model": "gpt-3.5-turbo",96"messages": [{"role": "user", "content": "What is deep learning?"}],97"max_tokens": 10098}99] * 100 # 300 requests total100101# Create requests file102requests_file = create_batch_requests_file(chat_requests, "batch_requests.jsonl")103104# Upload requests file105with open(requests_file, "rb") as f:106input_file = client.files.create(107file=f,108purpose="batch"109)110111print(f"Uploaded input file: {input_file.id}")112113# Create batch job114batch = client.batches.create(115input_file_id=input_file.id,116endpoint="/v1/chat/completions",117completion_window="24h",118metadata={"description": "ML questions batch", "project": "education"}119)120121print(f"Created batch: {batch.id}")122print(f"Status: {batch.status}")123print(f"Endpoint: {batch.endpoint}")124125# List batches126recent_batches = client.batches.list(limit=10)127128print("Recent batches:")129for batch_item in recent_batches:130print(f" {batch_item.id}: {batch_item.status} - {batch_item.endpoint}")131132# Retrieve specific batch133batch_info = client.batches.retrieve(batch.id)134135print(f"Batch details:")136print(f" ID: {batch_info.id}")137print(f" Status: {batch_info.status}")138print(f" Request counts: {batch_info.request_counts}")139print(f" Created: {batch_info.created_at}")140print(f" Metadata: {batch_info.metadata}")141```142143### Batch Monitoring and Results144145Monitor batch processing progress and retrieve results when completed.146147Usage examples:148149```python150import time151152def monitor_batch_progress(batch_id: str):153"""Monitor batch until completion"""154155print(f"Monitoring batch {batch_id}...")156157while True:158batch = client.batches.retrieve(batch_id)159160status = batch.status161request_counts = batch.request_counts162163print(f"Status: {status}")164165if request_counts:166total = request_counts.total167completed = request_counts.completed168failed = request_counts.failed169170if total > 0:171progress = (completed + failed) / total * 100172print(f"Progress: {progress:.1f}% ({completed} completed, {failed} failed of {total})")173174if status in ["completed", "failed", "cancelled", "expired"]:175print(f"Batch finished with status: {status}")176return batch177178# Wait before checking again179time.sleep(30)180181return batch182183# Monitor batch184final_batch = monitor_batch_progress(batch.id)185186# Download results when completed187if final_batch.status == "completed":188# Get output file189output_file_id = final_batch.output_file_id190191if output_file_id:192# Download results193output_content = client.files.content(output_file_id)194195# Save results file196with open("batch_results.jsonl", "wb") as f:197f.write(output_content.content)198199print("Results downloaded to batch_results.jsonl")200201# Process results202process_batch_results("batch_results.jsonl")203204def process_batch_results(results_file: str):205"""Process and analyze batch results"""206207results = []208errors = []209210with open(results_file, 'r') as f:211for line in f:212result = json.loads(line)213214if result.get('error'):215errors.append(result)216else:217results.append(result)218219print(f"Processed {len(results)} successful results")220print(f"Found {len(errors)} errors")221222# Analyze successful results223for result in results[:5]: # Show first 5224custom_id = result.get('custom_id')225response = result.get('response', {})226body = response.get('body', {})227228if 'choices' in body:229content = body['choices'][0]['message']['content']230print(f"{custom_id}: {content[:100]}...")231232# Show errors if any233for error in errors[:3]: # Show first 3 errors234custom_id = error.get('custom_id')235error_info = error.get('error', {})236print(f"Error in {custom_id}: {error_info}")237238return results, errors239240# Get error file if available241if final_batch.error_file_id:242error_content = client.files.content(final_batch.error_file_id)243244with open("batch_errors.jsonl", "wb") as f:245f.write(error_content.content)246247print("Error details downloaded to batch_errors.jsonl")248```249250### Embeddings Batch Processing251252Process large volumes of text embeddings efficiently using batch operations.253254Usage examples:255256```python257# Prepare embeddings batch258def create_embeddings_batch(texts: list, model: str = "text-embedding-3-small"):259"""Create embeddings batch requests"""260261requests = []262263for i, text in enumerate(texts):264request = {265"custom_id": f"embedding-{i}",266"method": "POST",267"url": "/v1/embeddings",268"body": {269"model": model,270"input": text271}272}273requests.append(request)274275return requests276277# Large text dataset for embeddings278texts = [279"Machine learning is a method of data analysis",280"Deep learning uses neural networks with multiple layers",281"Natural language processing enables computers to understand text",282"Computer vision allows machines to interpret visual information",283"Reinforcement learning learns through trial and error"284] * 1000 # 5000 texts285286# Create embeddings batch287embeddings_requests = create_embeddings_batch(texts)288289# Save to file290embeddings_file = "embeddings_batch.jsonl"291with open(embeddings_file, 'w') as f:292for request in embeddings_requests:293f.write(json.dumps(request) + '\n')294295# Upload and create batch296with open(embeddings_file, "rb") as f:297embeddings_input_file = client.files.create(298file=f,299purpose="batch"300)301302embeddings_batch = client.batches.create(303input_file_id=embeddings_input_file.id,304endpoint="/v1/embeddings",305completion_window="24h",306metadata={"type": "embeddings", "count": str(len(texts))}307)308309print(f"Embeddings batch created: {embeddings_batch.id}")310311# Monitor embeddings batch312def monitor_embeddings_batch(batch_id: str):313"""Monitor embeddings batch with specific processing"""314315final_batch = monitor_batch_progress(batch_id)316317if final_batch.status == "completed":318# Download embeddings319output_content = client.files.content(final_batch.output_file_id)320321# Process embeddings results322embeddings_data = []323324with open("temp_embeddings.jsonl", "wb") as f:325f.write(output_content.content)326327with open("temp_embeddings.jsonl", "r") as f:328for line in f:329result = json.loads(line)330331if not result.get('error'):332response = result['response']['body']333embedding = response['data'][0]['embedding']334custom_id = result['custom_id']335336embeddings_data.append({337'id': custom_id,338'embedding': embedding,339'text': texts[int(custom_id.split('-')[1])]340})341342print(f"Processed {len(embeddings_data)} embeddings")343344# Save processed embeddings345with open("processed_embeddings.json", "w") as f:346json.dump(embeddings_data, f)347348return embeddings_data349350# Process when complete351# embeddings_results = monitor_embeddings_batch(embeddings_batch.id)352```353354### Legacy Completions Batch Processing355356Handle batch processing for legacy text completion models.357358Usage examples:359360```python361# Create completions batch requests362def create_completions_batch(prompts: list, model: str = "gpt-3.5-turbo-instruct"):363"""Create text completions batch requests"""364365requests = []366367for i, prompt in enumerate(prompts):368request = {369"custom_id": f"completion-{i}",370"method": "POST",371"url": "/v1/completions",372"body": {373"model": model,374"prompt": prompt,375"max_tokens": 150,376"temperature": 0.7377}378}379requests.append(request)380381return requests382383# Completion prompts384completion_prompts = [385"Once upon a time in a distant galaxy,",386"The future of artificial intelligence is",387"In the world of quantum computing,",388"The benefits of renewable energy include",389"The most important discovery in science was"390] * 200 # 1000 prompts391392# Create completions batch393completions_requests = create_completions_batch(completion_prompts)394395completions_file = "completions_batch.jsonl"396with open(completions_file, 'w') as f:397for request in completions_requests:398f.write(json.dumps(request) + '\n')399400# Upload and create batch401with open(completions_file, "rb") as f:402completions_input_file = client.files.create(403file=f,404purpose="batch"405)406407completions_batch = client.batches.create(408input_file_id=completions_input_file.id,409endpoint="/v1/completions",410completion_window="24h",411metadata={"type": "text_completions"}412)413414print(f"Completions batch created: {completions_batch.id}")415```416417### Advanced Batch Management418419Implement advanced batch management with error handling, retry logic, and optimization.420421Usage examples:422423```python424from typing import List, Dict, Any425import os426427class BatchManager:428"""Advanced batch processing management"""429430def __init__(self, client):431self.client = client432self.active_batches = {}433434def create_optimized_batch(self, requests: List[Dict], endpoint: str,435batch_size: int = 50000, **kwargs):436"""Create optimized batches with size limits"""437438if len(requests) <= batch_size:439# Single batch440return [self._create_single_batch(requests, endpoint, **kwargs)]441442# Split into multiple batches443batches = []444for i in range(0, len(requests), batch_size):445batch_requests = requests[i:i + batch_size]446batch = self._create_single_batch(447batch_requests,448endpoint,449suffix=f"_part_{i//batch_size + 1}",450**kwargs451)452batches.append(batch)453454return batches455456def _create_single_batch(self, requests: List[Dict], endpoint: str,457suffix: str = "", **kwargs):458"""Create single batch from requests"""459460# Create temporary file461temp_file = f"batch_requests{suffix}.jsonl"462463with open(temp_file, 'w') as f:464for request in requests:465f.write(json.dumps(request) + '\n')466467# Upload file468with open(temp_file, "rb") as f:469input_file = self.client.files.create(470file=f,471purpose="batch"472)473474# Create batch475batch = self.client.batches.create(476input_file_id=input_file.id,477endpoint=endpoint,478completion_window="24h",479**kwargs480)481482# Track batch483self.active_batches[batch.id] = {484'batch': batch,485'temp_file': temp_file,486'request_count': len(requests)487}488489# Clean up temp file490os.remove(temp_file)491492return batch493494def monitor_all_batches(self):495"""Monitor all active batches"""496497completed_batches = []498499for batch_id in list(self.active_batches.keys()):500batch = self.client.batches.retrieve(batch_id)501502print(f"Batch {batch_id}: {batch.status}")503504if batch.status in ["completed", "failed", "cancelled", "expired"]:505completed_batches.append(batch_id)506507# Process completed batch508self._process_completed_batch(batch_id, batch)509510# Remove completed batches511for batch_id in completed_batches:512del self.active_batches[batch_id]513514return len(self.active_batches) == 0 # All done515516def _process_completed_batch(self, batch_id: str, batch):517"""Process completed batch results"""518519if batch.status == "completed" and batch.output_file_id:520# Download results521output_content = self.client.files.content(batch.output_file_id)522523results_file = f"results_{batch_id}.jsonl"524with open(results_file, "wb") as f:525f.write(output_content.content)526527print(f"Results saved to {results_file}")528529# Process errors if available530if batch.error_file_id:531error_content = self.client.files.content(batch.error_file_id)532533errors_file = f"errors_{batch_id}.jsonl"534with open(errors_file, "wb") as f:535f.write(error_content.content)536537print(f"Errors saved to {errors_file}")538539def cancel_all_batches(self):540"""Cancel all active batches"""541542for batch_id in self.active_batches:543try:544self.client.batches.cancel(batch_id)545print(f"Cancelled batch {batch_id}")546except Exception as e:547print(f"Failed to cancel {batch_id}: {e}")548549# Example usage550batch_manager = BatchManager(client)551552# Create large batch job553large_requests = chat_requests * 500 # 150,000 requests554555# This will automatically split into multiple batches556batches = batch_manager.create_optimized_batch(557large_requests,558"/v1/chat/completions",559metadata={"project": "large_scale_processing"}560)561562print(f"Created {len(batches)} batches for {len(large_requests)} requests")563564# Monitor progress565while not batch_manager.monitor_all_batches():566print("Waiting for batches to complete...")567time.sleep(60)568569print("All batches completed!")570571# Cost estimation572def estimate_batch_cost(requests: List[Dict], endpoint: str):573"""Estimate batch processing cost"""574575# Approximate token counts and costs576costs = {577"/v1/chat/completions": {"input": 0.0015, "output": 0.002}, # per 1K tokens578"/v1/completions": {"input": 0.0015, "output": 0.002},579"/v1/embeddings": {"input": 0.0001, "output": 0}580}581582if endpoint not in costs:583return "Unknown endpoint"584585# Simple estimation (would need actual token counting)586avg_tokens_per_request = 100 # Rough estimate587total_tokens = len(requests) * avg_tokens_per_request588589cost_per_1k = costs[endpoint]["input"]590estimated_cost = (total_tokens / 1000) * cost_per_1k591592# 50% discount for batch API593batch_cost = estimated_cost * 0.5594595return {596"requests": len(requests),597"estimated_tokens": total_tokens,598"regular_cost": estimated_cost,599"batch_cost": batch_cost,600"savings": estimated_cost - batch_cost601}602603# Estimate cost604cost_estimate = estimate_batch_cost(large_requests, "/v1/chat/completions")605print(f"Cost estimate: {cost_estimate}")606```607608## Types609610### Core Response Types611612```python { .api }613class Batch(BaseModel):614id: str615completion_window: str616created_at: int617endpoint: str618input_file_id: str619object: Literal["batch"]620status: BatchStatus621cancelled_at: Optional[int]622cancelling_at: Optional[int]623completed_at: Optional[int]624error_file_id: Optional[str]625errors: Optional[BatchErrors]626expired_at: Optional[int]627expires_at: Optional[int]628failed_at: Optional[int]629finalizing_at: Optional[int]630in_progress_at: Optional[int]631metadata: Optional[Dict[str, str]]632output_file_id: Optional[str]633request_counts: Optional[BatchRequestCounts]634635class BatchRequestCounts(BaseModel):636completed: int637failed: int638total: int639640class BatchErrors(BaseModel):641data: List[BatchError]642object: Literal["list"]643644class BatchError(BaseModel):645code: Optional[str]646line: Optional[int]647message: Optional[str]648param: Optional[str]649```650651### Parameter Types652653```python { .api }654# Batch creation parameters655BatchCreateParams = TypedDict('BatchCreateParams', {656'completion_window': Required[Literal["24h"]],657'endpoint': Required[Literal["/v1/chat/completions", "/v1/embeddings", "/v1/completions"]],658'input_file_id': Required[str],659'metadata': NotRequired[Optional[Dict[str, str]]],660}, total=False)661662# Batch request format663class BatchRequest(TypedDict, total=False):664custom_id: Required[str]665method: Required[Literal["POST"]]666url: Required[str]667body: Required[Dict[str, Any]]668669# Batch response format670class BatchResponse(TypedDict, total=False):671id: str672custom_id: str673response: Optional[BatchResponseData]674error: Optional[BatchResponseError]675676class BatchResponseData(TypedDict, total=False):677status_code: int678request_id: str679body: Dict[str, Any]680681class BatchResponseError(TypedDict, total=False):682code: str683message: str684```685686### Status and Configuration Types687688```python { .api }689# Batch status enumeration690BatchStatus = Literal[691"validating",692"failed",693"in_progress",694"finalizing",695"completed",696"expired",697"cancelling",698"cancelled"699]700701# Supported endpoints702BatchEndpoint = Literal[703"/v1/chat/completions",704"/v1/embeddings",705"/v1/completions"706]707708# Completion windows709CompletionWindow = Literal["24h"]710711# Batch limits and configuration712class BatchLimits:713max_requests_per_batch: int = 50000714max_file_size_mb: int = 100715completion_window_hours: int = 24716717# Cost savings718discount_percentage: float = 50.0 # 50% discount vs regular API719720# Rate limits721max_queued_batches: int = 50722max_total_requests: int = 2000000 # Across all batches723724# Supported models by endpoint725supported_models = {726"/v1/chat/completions": [727"gpt-4o", "gpt-4o-mini", "gpt-4-turbo", "gpt-4",728"gpt-3.5-turbo", "gpt-3.5-turbo-0125"729],730"/v1/completions": [731"gpt-3.5-turbo-instruct", "davinci-002", "babbage-002"732],733"/v1/embeddings": [734"text-embedding-3-large", "text-embedding-3-small",735"text-embedding-ada-002"736]737}738```739740## Best Practices741742### Batch Design743744- Group similar requests together for optimal processing745- Use descriptive custom IDs for easy result identification746- Keep batch sizes under the 50,000 request limit747- Include relevant metadata for tracking and organization748749### Cost Optimization750751- Use batch API for 50% cost savings on large volumes752- Batch requests during off-peak hours when possible753- Optimize request parameters to minimize token usage754- Monitor usage across multiple batches755756### Error Handling757758- Always check both output and error files759- Implement retry logic for failed requests760- Validate request format before batch submission761- Monitor batch status and handle timeouts appropriately762763### File Management764765- Clean up uploaded batch files after processing766- Organize results files with clear naming conventions767- Download and process results promptly after completion768- Keep backups of important batch results769770### Performance Considerations771772- Submit batches during periods of lower API usage773- Plan for 24-hour completion windows in your workflows774- Consider splitting very large datasets across multiple batches775- Use appropriate completion windows based on urgency needs776777### Monitoring and Maintenance778779- Implement comprehensive batch monitoring systems780- Set up alerts for batch completion or failures781- Track batch processing times and success rates782- Regularly review and optimize batch processing workflows