llm_batch_helper 0.1.5__tar.gz → 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: llm_batch_helper
3
- Version: 0.1.5
3
+ Version: 0.2.0
4
4
  Summary: A Python package that enables batch submission of prompts to LLM APIs, with built-in async capabilities and response caching.
5
5
  License: MIT
6
- Keywords: llm,openai,together,batch,async,ai,nlp,api
6
+ Keywords: llm,openai,together,openrouter,batch,async,ai,nlp,api
7
7
  Author: Tianyi Peng
8
8
  Author-email: tianyipeng95@gmail.com
9
9
  Requires-Python: >=3.11,<4.0
@@ -19,7 +19,6 @@ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
19
19
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
20
20
  Requires-Dist: httpx (>=0.24.0,<2.0.0)
21
21
  Requires-Dist: openai (>=1.0.0,<2.0.0)
22
- Requires-Dist: python-dotenv (>=1.0.0,<2.0.0)
23
22
  Requires-Dist: tenacity (>=8.0.0,<9.0.0)
24
23
  Requires-Dist: tqdm (>=4.65.0,<5.0.0)
25
24
  Project-URL: Homepage, https://github.com/TianyiPeng/LLM_batch_helper
@@ -28,7 +27,29 @@ Description-Content-Type: text/markdown
28
27
 
29
28
  # LLM Batch Helper
30
29
 
31
- A Python package that enables batch submission of prompts to LLM APIs, with built-in async capabilities and response caching.
30
+ [![PyPI version](https://badge.fury.io/py/llm_batch_helper.svg)](https://badge.fury.io/py/llm_batch_helper)
31
+ [![Downloads](https://pepy.tech/badge/llm_batch_helper)](https://pepy.tech/project/llm_batch_helper)
32
+ [![Downloads/Month](https://pepy.tech/badge/llm_batch_helper/month)](https://pepy.tech/project/llm_batch_helper)
33
+ [![Documentation Status](https://readthedocs.org/projects/llm-batch-helper/badge/?version=latest)](https://llm-batch-helper.readthedocs.io/en/latest/?badge=latest)
34
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
35
+
36
+ A Python package that enables batch submission of prompts to LLM APIs, with built-in async capabilities, response caching, prompt verification, and more. This package is designed to streamline applications like LLM simulation, LLM-as-a-judge, and other batch processing scenarios.
37
+
38
+ 📖 **[Complete Documentation](https://llm-batch-helper.readthedocs.io/)** | 🚀 **[Quick Start Guide](https://llm-batch-helper.readthedocs.io/en/latest/quickstart.html)**
39
+
40
+ ## Why we designed this package
41
+
42
+ Calling LLM APIs has become increasingly common, but several pain points exist in practice:
43
+
44
+ 1. **Efficient Batch Processing**: How do you run LLM calls in batches efficiently? Our async implementation is 3X-100X faster than multi-thread/multi-process approaches.
45
+
46
+ 2. **API Reliability**: LLM APIs can be unstable, so we need robust retry mechanisms when calls get interrupted.
47
+
48
+ 3. **Long-Running Simulations**: During long-running LLM simulations, computers can crash and APIs can fail. Can we cache LLM API calls to avoid repeating completed work?
49
+
50
+ 4. **Output Validation**: LLM outputs often have format requirements. If the output isn't right, we need to retry with validation.
51
+
52
+ This package is designed to solve these exact pain points with async processing, intelligent caching, and comprehensive error handling. If there are some additional features you need, please post an issue.
32
53
 
33
54
  ## Features
34
55
 
@@ -67,6 +88,7 @@ poetry shell
67
88
 
68
89
  ### 1. Set up environment variables
69
90
 
91
+ **Option A: Environment Variables**
70
92
  ```bash
71
93
  # For OpenAI
72
94
  export OPENAI_API_KEY="your-openai-api-key"
@@ -75,6 +97,22 @@ export OPENAI_API_KEY="your-openai-api-key"
75
97
  export TOGETHER_API_KEY="your-together-api-key"
76
98
  ```
77
99
 
100
+ **Option B: .env File (Recommended for Development)**
101
+ ```python
102
+ # In your script, before importing llm_batch_helper
103
+ from dotenv import load_dotenv
104
+ load_dotenv() # Load from .env file
105
+
106
+ # Then use the package normally
107
+ from llm_batch_helper import LLMConfig, process_prompts_batch
108
+ ```
109
+
110
+ Create a `.env` file in your project:
111
+ ```
112
+ OPENAI_API_KEY=your-openai-api-key
113
+ TOGETHER_API_KEY=your-together-api-key
114
+ ```
115
+
78
116
  ### 2. Interactive Tutorial (Recommended)
79
117
 
80
118
  Check out the comprehensive Jupyter notebook [tutorial](https://github.com/TianyiPeng/LLM_batch_helper/blob/main/tutorials/llm_batch_helper_tutorial.ipynb).
@@ -85,8 +123,12 @@ The tutorial covers all features with interactive examples!
85
123
 
86
124
  ```python
87
125
  import asyncio
126
+ from dotenv import load_dotenv # Optional: for .env file support
88
127
  from llm_batch_helper import LLMConfig, process_prompts_batch
89
128
 
129
+ # Optional: Load environment variables from .env file
130
+ load_dotenv()
131
+
90
132
  async def main():
91
133
  # Create configuration
92
134
  config = LLMConfig(
@@ -203,7 +245,7 @@ Main function for batch processing of prompts.
203
245
  ```python
204
246
  async def process_prompts_batch(
205
247
  config: LLMConfig,
206
- provider: str, # "openai" or "together"
248
+ provider: str, # "openai", "together", or "openrouter"
207
249
  prompts: Optional[List[str]] = None,
208
250
  input_dir: Optional[str] = None,
209
251
  cache_dir: str = "llm_cache",
@@ -1,6 +1,28 @@
1
1
  # LLM Batch Helper
2
2
 
3
- A Python package that enables batch submission of prompts to LLM APIs, with built-in async capabilities and response caching.
3
+ [![PyPI version](https://badge.fury.io/py/llm_batch_helper.svg)](https://badge.fury.io/py/llm_batch_helper)
4
+ [![Downloads](https://pepy.tech/badge/llm_batch_helper)](https://pepy.tech/project/llm_batch_helper)
5
+ [![Downloads/Month](https://pepy.tech/badge/llm_batch_helper/month)](https://pepy.tech/project/llm_batch_helper)
6
+ [![Documentation Status](https://readthedocs.org/projects/llm-batch-helper/badge/?version=latest)](https://llm-batch-helper.readthedocs.io/en/latest/?badge=latest)
7
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
8
+
9
+ A Python package that enables batch submission of prompts to LLM APIs, with built-in async capabilities, response caching, prompt verification, and more. This package is designed to streamline applications like LLM simulation, LLM-as-a-judge, and other batch processing scenarios.
10
+
11
+ 📖 **[Complete Documentation](https://llm-batch-helper.readthedocs.io/)** | 🚀 **[Quick Start Guide](https://llm-batch-helper.readthedocs.io/en/latest/quickstart.html)**
12
+
13
+ ## Why we designed this package
14
+
15
+ Calling LLM APIs has become increasingly common, but several pain points exist in practice:
16
+
17
+ 1. **Efficient Batch Processing**: How do you run LLM calls in batches efficiently? Our async implementation is 3X-100X faster than multi-thread/multi-process approaches.
18
+
19
+ 2. **API Reliability**: LLM APIs can be unstable, so we need robust retry mechanisms when calls get interrupted.
20
+
21
+ 3. **Long-Running Simulations**: During long-running LLM simulations, computers can crash and APIs can fail. Can we cache LLM API calls to avoid repeating completed work?
22
+
23
+ 4. **Output Validation**: LLM outputs often have format requirements. If the output isn't right, we need to retry with validation.
24
+
25
+ This package is designed to solve these exact pain points with async processing, intelligent caching, and comprehensive error handling. If there are some additional features you need, please post an issue.
4
26
 
5
27
  ## Features
6
28
 
@@ -39,6 +61,7 @@ poetry shell
39
61
 
40
62
  ### 1. Set up environment variables
41
63
 
64
+ **Option A: Environment Variables**
42
65
  ```bash
43
66
  # For OpenAI
44
67
  export OPENAI_API_KEY="your-openai-api-key"
@@ -47,6 +70,22 @@ export OPENAI_API_KEY="your-openai-api-key"
47
70
  export TOGETHER_API_KEY="your-together-api-key"
48
71
  ```
49
72
 
73
+ **Option B: .env File (Recommended for Development)**
74
+ ```python
75
+ # In your script, before importing llm_batch_helper
76
+ from dotenv import load_dotenv
77
+ load_dotenv() # Load from .env file
78
+
79
+ # Then use the package normally
80
+ from llm_batch_helper import LLMConfig, process_prompts_batch
81
+ ```
82
+
83
+ Create a `.env` file in your project:
84
+ ```
85
+ OPENAI_API_KEY=your-openai-api-key
86
+ TOGETHER_API_KEY=your-together-api-key
87
+ ```
88
+
50
89
  ### 2. Interactive Tutorial (Recommended)
51
90
 
52
91
  Check out the comprehensive Jupyter notebook [tutorial](https://github.com/TianyiPeng/LLM_batch_helper/blob/main/tutorials/llm_batch_helper_tutorial.ipynb).
@@ -57,8 +96,12 @@ The tutorial covers all features with interactive examples!
57
96
 
58
97
  ```python
59
98
  import asyncio
99
+ from dotenv import load_dotenv # Optional: for .env file support
60
100
  from llm_batch_helper import LLMConfig, process_prompts_batch
61
101
 
102
+ # Optional: Load environment variables from .env file
103
+ load_dotenv()
104
+
62
105
  async def main():
63
106
  # Create configuration
64
107
  config = LLMConfig(
@@ -175,7 +218,7 @@ Main function for batch processing of prompts.
175
218
  ```python
176
219
  async def process_prompts_batch(
177
220
  config: LLMConfig,
178
- provider: str, # "openai" or "together"
221
+ provider: str, # "openai", "together", or "openrouter"
179
222
  prompts: Optional[List[str]] = None,
180
223
  input_dir: Optional[str] = None,
181
224
  cache_dir: str = "llm_cache",
@@ -3,7 +3,7 @@ from .config import LLMConfig
3
3
  from .input_handlers import get_prompts, read_prompt_files, read_prompt_list
4
4
  from .providers import process_prompts_batch
5
5
 
6
- __version__ = "0.1.5"
6
+ __version__ = "0.2.0"
7
7
 
8
8
  __all__ = [
9
9
  "LLMCache",
@@ -16,6 +16,7 @@ class LLMConfig:
16
16
  verification_callback: Optional[Callable[..., bool]] = None,
17
17
  verification_callback_args: Optional[Dict] = None,
18
18
  max_completion_tokens: Optional[int] = None,
19
+ **kwargs
19
20
  ):
20
21
  self.model_name = model_name
21
22
  self.temperature = temperature
@@ -30,3 +31,4 @@ class LLMConfig:
30
31
  self.verification_callback_args = (
31
32
  verification_callback_args if verification_callback_args is not None else {}
32
33
  )
34
+ self.kwargs = kwargs
@@ -4,7 +4,6 @@ from typing import Any, Dict, List, Optional, Tuple, Union
4
4
 
5
5
  import httpx
6
6
  import openai
7
- from dotenv import load_dotenv
8
7
  from tenacity import retry, retry_if_exception_type, stop_after_attempt, wait_exponential
9
8
  from tqdm.asyncio import tqdm_asyncio
10
9
 
@@ -12,8 +11,6 @@ from .cache import LLMCache
12
11
  from .config import LLMConfig
13
12
  from .input_handlers import get_prompts
14
13
 
15
- load_dotenv()
16
-
17
14
 
18
15
  @retry(
19
16
  stop=stop_after_attempt(5),
@@ -49,6 +46,7 @@ async def _get_openai_response_direct(
49
46
  messages=messages,
50
47
  temperature=config.temperature,
51
48
  max_completion_tokens=config.max_completion_tokens,
49
+ **config.kwargs,
52
50
  )
53
51
  usage_details = {
54
52
  "prompt_token_count": response.usage.prompt_tokens,
@@ -97,6 +95,7 @@ async def _get_together_response_direct(
97
95
  "messages": messages,
98
96
  "temperature": config.temperature,
99
97
  "max_tokens": config.max_completion_tokens,
98
+ **config.kwargs,
100
99
  }
101
100
 
102
101
  response = await client.post(
@@ -119,6 +118,66 @@ async def _get_together_response_direct(
119
118
  "usage_details": usage_details,
120
119
  }
121
120
 
121
+
122
+ @retry(
123
+ stop=stop_after_attempt(5),
124
+ wait=wait_exponential(multiplier=1, min=4, max=60),
125
+ retry=retry_if_exception_type(
126
+ (
127
+ ConnectionError,
128
+ TimeoutError,
129
+ httpx.HTTPStatusError,
130
+ httpx.RequestError,
131
+ )
132
+ ),
133
+ reraise=True,
134
+ )
135
+ async def _get_openrouter_response_direct(
136
+ prompt: str, config: LLMConfig
137
+ ) -> Dict[str, Union[str, Dict]]:
138
+ api_key = os.environ.get("OPENROUTER_API_KEY")
139
+ if not api_key:
140
+ raise ValueError("OPENROUTER_API_KEY environment variable not set")
141
+
142
+ async with httpx.AsyncClient(timeout=1000.0) as client:
143
+ messages = [
144
+ {"role": "system", "content": config.system_instruction},
145
+ {"role": "user", "content": prompt},
146
+ ]
147
+
148
+ headers = {
149
+ "Authorization": f"Bearer {api_key}",
150
+ "Content-Type": "application/json",
151
+ }
152
+
153
+ payload = {
154
+ "model": config.model_name,
155
+ "messages": messages,
156
+ "temperature": config.temperature,
157
+ "max_tokens": config.max_completion_tokens,
158
+ **config.kwargs,
159
+ }
160
+
161
+ response = await client.post(
162
+ "https://openrouter.ai/api/v1/chat/completions",
163
+ json=payload,
164
+ headers=headers,
165
+ )
166
+ response.raise_for_status()
167
+
168
+ response_data = response.json()
169
+ usage = response_data.get("usage", {})
170
+ usage_details = {
171
+ "prompt_token_count": usage.get("prompt_tokens", 0),
172
+ "completion_token_count": usage.get("completion_tokens", 0),
173
+ "total_token_count": usage.get("total_tokens", 0),
174
+ }
175
+
176
+ return {
177
+ "response_text": response_data["choices"][0]["message"]["content"],
178
+ "usage_details": usage_details,
179
+ }
180
+
122
181
  async def get_llm_response_with_internal_retry(
123
182
  prompt_id: str,
124
183
  prompt: str,
@@ -138,6 +197,8 @@ async def get_llm_response_with_internal_retry(
138
197
  response = await _get_openai_response_direct(prompt, config)
139
198
  elif provider.lower() == "together":
140
199
  response = await _get_together_response_direct(prompt, config)
200
+ elif provider.lower() == "openrouter":
201
+ response = await _get_openrouter_response_direct(prompt, config)
141
202
  else:
142
203
  raise ValueError(f"Unsupported provider: {provider}")
143
204
 
@@ -168,7 +229,7 @@ async def process_prompts_batch(
168
229
  prompts: Optional list of prompts in any supported format (string, tuple, or dict)
169
230
  input_dir: Optional path to directory containing prompt files
170
231
  config: LLM configuration
171
- provider: LLM provider to use ("openai", "together", or "gemini")
232
+ provider: LLM provider to use ("openai", "together", or "openrouter")
172
233
  desc: Description for progress bar
173
234
  cache_dir: Optional directory for caching responses
174
235
  force: If True, force regeneration even if cached response exists
@@ -1,13 +1,13 @@
1
1
  [tool.poetry]
2
2
  name = "llm_batch_helper"
3
- version = "0.1.5"
3
+ version = "0.2.0"
4
4
  description = "A Python package that enables batch submission of prompts to LLM APIs, with built-in async capabilities and response caching."
5
5
  authors = ["Tianyi Peng <tianyipeng95@gmail.com>"]
6
6
  readme = "README.md"
7
7
  license = "MIT"
8
8
  homepage = "https://github.com/TianyiPeng/LLM_batch_helper"
9
9
  repository = "https://github.com/TianyiPeng/LLM_batch_helper"
10
- keywords = ["llm", "openai", "together", "batch", "async", "ai", "nlp", "api"]
10
+ keywords = ["llm", "openai", "together", "openrouter", "batch", "async", "ai", "nlp", "api"]
11
11
  classifiers = [
12
12
  "Development Status :: 4 - Beta",
13
13
  "Intended Audience :: Developers",
@@ -25,11 +25,11 @@ packages = [{include = "llm_batch_helper"}]
25
25
  python = "^3.11"
26
26
  httpx = ">=0.24.0,<2.0.0"
27
27
  openai = "^1.0.0"
28
- python-dotenv = "^1.0.0"
29
28
  tenacity = "^8.0.0"
30
29
  tqdm = "^4.65.0"
31
30
 
32
31
  [tool.poetry.group.dev.dependencies]
32
+ python-dotenv = "^1.0.0" # Optional for .env file support
33
33
  pytest = "^7.0.0"
34
34
  black = "^23.0.0"
35
35
  isort = "^5.12.0"