batchwork-ai 0.2.3__tar.gz → 0.3.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.
Files changed (64) hide show
  1. {batchwork_ai-0.2.3 → batchwork_ai-0.3.0}/PKG-INFO +30 -13
  2. {batchwork_ai-0.2.3 → batchwork_ai-0.3.0}/README.md +29 -12
  3. batchwork_ai-0.3.0/pyproject.toml +98 -0
  4. batchwork_ai-0.2.3/pyproject.toml → batchwork_ai-0.3.0/pyproject.toml.orig +1 -1
  5. {batchwork_ai-0.2.3 → batchwork_ai-0.3.0}/src/batchwork/__init__.py +30 -0
  6. {batchwork_ai-0.2.3 → batchwork_ai-0.3.0}/src/batchwork/_limits.py +1 -0
  7. {batchwork_ai-0.2.3 → batchwork_ai-0.3.0}/src/batchwork/body.py +430 -0
  8. {batchwork_ai-0.2.3 → batchwork_ai-0.3.0}/src/batchwork/cli/_commands.py +589 -3
  9. {batchwork_ai-0.2.3 → batchwork_ai-0.3.0}/src/batchwork/cli/_config.py +3 -2
  10. {batchwork_ai-0.2.3 → batchwork_ai-0.3.0}/src/batchwork/cli/_contract.py +58 -2
  11. {batchwork_ai-0.2.3 → batchwork_ai-0.3.0}/src/batchwork/cli/_human.py +20 -0
  12. {batchwork_ai-0.2.3 → batchwork_ai-0.3.0}/src/batchwork/cli/_input.py +438 -6
  13. {batchwork_ai-0.2.3 → batchwork_ai-0.3.0}/src/batchwork/cli/_registry.py +34 -8
  14. {batchwork_ai-0.2.3 → batchwork_ai-0.3.0}/src/batchwork/cli/_submit_text.py +610 -2
  15. {batchwork_ai-0.2.3 → batchwork_ai-0.3.0}/src/batchwork/cli/_volume.py +3 -0
  16. {batchwork_ai-0.2.3 → batchwork_ai-0.3.0}/src/batchwork/client.py +369 -64
  17. {batchwork_ai-0.2.3 → batchwork_ai-0.3.0}/src/batchwork/errors.py +1 -1
  18. {batchwork_ai-0.2.3 → batchwork_ai-0.3.0}/src/batchwork/providers/__init__.py +3 -0
  19. {batchwork_ai-0.2.3 → batchwork_ai-0.3.0}/src/batchwork/providers/_capabilities.py +1 -0
  20. batchwork_ai-0.3.0/src/batchwork/providers/azure.py +76 -0
  21. {batchwork_ai-0.2.3 → batchwork_ai-0.3.0}/src/batchwork/providers/openai_compatible.py +26 -3
  22. {batchwork_ai-0.2.3 → batchwork_ai-0.3.0}/src/batchwork/providers/shared.py +67 -0
  23. {batchwork_ai-0.2.3 → batchwork_ai-0.3.0}/src/batchwork/providers/xai.py +43 -2
  24. {batchwork_ai-0.2.3 → batchwork_ai-0.3.0}/src/batchwork/types.py +119 -0
  25. {batchwork_ai-0.2.3 → batchwork_ai-0.3.0}/LICENSE +0 -0
  26. {batchwork_ai-0.2.3 → batchwork_ai-0.3.0}/src/batchwork/_anthropic_serialization.py +0 -0
  27. {batchwork_ai-0.2.3 → batchwork_ai-0.3.0}/src/batchwork/_base_url.py +0 -0
  28. {batchwork_ai-0.2.3 → batchwork_ai-0.3.0}/src/batchwork/_bounded_json.py +0 -0
  29. {batchwork_ai-0.2.3 → batchwork_ai-0.3.0}/src/batchwork/_compatible_media.py +0 -0
  30. {batchwork_ai-0.2.3 → batchwork_ai-0.3.0}/src/batchwork/_google_schema.py +0 -0
  31. {batchwork_ai-0.2.3 → batchwork_ai-0.3.0}/src/batchwork/_google_serialization.py +0 -0
  32. {batchwork_ai-0.2.3 → batchwork_ai-0.3.0}/src/batchwork/_network.py +0 -0
  33. {batchwork_ai-0.2.3 → batchwork_ai-0.3.0}/src/batchwork/_provider_failure.py +0 -0
  34. {batchwork_ai-0.2.3 → batchwork_ai-0.3.0}/src/batchwork/_read_retry.py +0 -0
  35. {batchwork_ai-0.2.3 → batchwork_ai-0.3.0}/src/batchwork/_serialization.py +0 -0
  36. {batchwork_ai-0.2.3 → batchwork_ai-0.3.0}/src/batchwork/_text_validation.py +0 -0
  37. {batchwork_ai-0.2.3 → batchwork_ai-0.3.0}/src/batchwork/_typing.py +0 -0
  38. {batchwork_ai-0.2.3 → batchwork_ai-0.3.0}/src/batchwork/cli/__init__.py +0 -0
  39. {batchwork_ai-0.2.3 → batchwork_ai-0.3.0}/src/batchwork/cli/_failures.py +0 -0
  40. {batchwork_ai-0.2.3 → batchwork_ai-0.3.0}/src/batchwork/cli/_lifecycle.py +0 -0
  41. {batchwork_ai-0.2.3 → batchwork_ai-0.3.0}/src/batchwork/cli/_materialize.py +0 -0
  42. {batchwork_ai-0.2.3 → batchwork_ai-0.3.0}/src/batchwork/cli/_output.py +0 -0
  43. {batchwork_ai-0.2.3 → batchwork_ai-0.3.0}/src/batchwork/cli/_state.py +0 -0
  44. {batchwork_ai-0.2.3 → batchwork_ai-0.3.0}/src/batchwork/job.py +0 -0
  45. {batchwork_ai-0.2.3 → batchwork_ai-0.3.0}/src/batchwork/media.py +0 -0
  46. {batchwork_ai-0.2.3 → batchwork_ai-0.3.0}/src/batchwork/providers/_image.py +0 -0
  47. {batchwork_ai-0.2.3 → batchwork_ai-0.3.0}/src/batchwork/providers/adapter.py +0 -0
  48. {batchwork_ai-0.2.3 → batchwork_ai-0.3.0}/src/batchwork/providers/anthropic.py +0 -0
  49. {batchwork_ai-0.2.3 → batchwork_ai-0.3.0}/src/batchwork/providers/google.py +0 -0
  50. {batchwork_ai-0.2.3 → batchwork_ai-0.3.0}/src/batchwork/providers/groq.py +0 -0
  51. {batchwork_ai-0.2.3 → batchwork_ai-0.3.0}/src/batchwork/providers/ids.py +0 -0
  52. {batchwork_ai-0.2.3 → batchwork_ai-0.3.0}/src/batchwork/providers/mistral.py +0 -0
  53. {batchwork_ai-0.2.3 → batchwork_ai-0.3.0}/src/batchwork/providers/openai.py +0 -0
  54. {batchwork_ai-0.2.3 → batchwork_ai-0.3.0}/src/batchwork/providers/together.py +0 -0
  55. {batchwork_ai-0.2.3 → batchwork_ai-0.3.0}/src/batchwork/py.typed +0 -0
  56. {batchwork_ai-0.2.3 → batchwork_ai-0.3.0}/src/batchwork/server/__init__.py +0 -0
  57. {batchwork_ai-0.2.3 → batchwork_ai-0.3.0}/src/batchwork/server/models.py +0 -0
  58. {batchwork_ai-0.2.3 → batchwork_ai-0.3.0}/src/batchwork/server/poller.py +0 -0
  59. {batchwork_ai-0.2.3 → batchwork_ai-0.3.0}/src/batchwork/server/signing.py +0 -0
  60. {batchwork_ai-0.2.3 → batchwork_ai-0.3.0}/src/batchwork/server/transport.py +0 -0
  61. {batchwork_ai-0.2.3 → batchwork_ai-0.3.0}/src/batchwork/stores/__init__.py +0 -0
  62. {batchwork_ai-0.2.3 → batchwork_ai-0.3.0}/src/batchwork/stores/base.py +0 -0
  63. {batchwork_ai-0.2.3 → batchwork_ai-0.3.0}/src/batchwork/stores/memory.py +0 -0
  64. {batchwork_ai-0.2.3 → batchwork_ai-0.3.0}/src/batchwork/stores/redis.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: batchwork-ai
3
- Version: 0.2.3
3
+ Version: 0.3.0
4
4
  Summary: Unified async batch API for AI providers
5
5
  Keywords: ai,anthropic,batch,gemini,llm,openai
6
6
  Author: Ajanraj
@@ -34,10 +34,10 @@ Description-Content-Type: text/markdown
34
34
 
35
35
  ![Batchwork — one typed API for provider-native AI batch jobs](docs/public/og-image.png)
36
36
 
37
- Unified async batch API for OpenAI, Anthropic, Google Gemini, Groq, Mistral, Together AI, and xAI. Providers price eligible batch requests up to 50% below standard synchronous calls, and Batchwork gives you that pricing through one typed Python interface and one CLI. It handles provider-specific serialization, submission, polling, and result parsing so you do not have to. Pricing and eligibility remain provider- and model-specific.
37
+ Unified async batch API for OpenAI, Azure OpenAI, Anthropic, Google Gemini, Groq, Mistral, Together AI, and xAI. Providers price eligible batch requests up to 50% below standard synchronous calls, and Batchwork gives you that pricing through one typed Python interface and one CLI. It handles provider-specific serialization, submission, polling, and result parsing so you do not have to. Pricing and eligibility remain provider- and model-specific.
38
38
 
39
39
  - One typed API for provider-native batch jobs
40
- - Text, embedding, and image workloads
40
+ - Text, embedding, image, image-edit, moderation, transcription, translation, and video workloads
41
41
  - Normalized jobs, results, usage, and errors
42
42
  - Messages, tools, structured content, and remote media
43
43
  - Polling, persistent stores, and signed webhooks
@@ -129,21 +129,38 @@ asyncio.run(main())
129
129
 
130
130
  Submitting returns a `BatchJob` immediately. Provider processing is asynchronous and may take minutes or, depending on the provider and workload, up to 24 hours.
131
131
 
132
+ Beyond text, the same client covers seven more modalities — for example hosted-audio transcription:
133
+
134
+ ```python
135
+ from batchwork import BatchTranscriptionRequest
136
+
137
+ job = await client.batch_transcriptions(
138
+ model="groq/whisper-large-v3",
139
+ requests=[
140
+ BatchTranscriptionRequest(
141
+ custom_id="call-1",
142
+ audio_url="https://example.com/call-1.mp3",
143
+ )
144
+ ],
145
+ )
146
+ ```
147
+
132
148
  Models use `provider/model` form. Results are correlated with requests through `custom_id`; provider output order is not guaranteed.
133
149
 
134
150
  ## Providers
135
151
 
136
152
  Output workloads supported by Batchwork:
137
153
 
138
- | Provider | Text | Embeddings | Image generation |
139
- | ------------- | ---- | ---------- | ---------------- |
140
- | OpenAI | Yes | Yes | Yes |
141
- | Anthropic | Yes | No | No |
142
- | Google Gemini | Yes | Yes | Yes |
143
- | Groq | Yes | No | No |
144
- | Mistral | Yes | Yes | No |
145
- | Together AI | Yes | No | No |
146
- | xAI | Yes | No | Yes |
154
+ | Provider | Text | Embeddings | Image generation | Image edits | Moderation | Transcription | Translation | Video |
155
+ | --- | --- | --- | --- | --- | --- | --- | --- | --- |
156
+ | OpenAI | Yes | Yes | Yes | Yes | Yes | No | No | No |
157
+ | Azure OpenAI | Yes | No | No | No | No | No | No | No |
158
+ | Anthropic | Yes | No | No | No | No | No | No | No |
159
+ | Google Gemini | Yes | Yes | Yes | No | No | No | No | No |
160
+ | Groq | Yes | No | No | No | No | Yes | Yes | No |
161
+ | Mistral | Yes | Yes | No | No | Yes | Yes | No | No |
162
+ | Together AI | Yes | No | No | No | No | Yes | Yes | No |
163
+ | xAI | Yes | No | Yes | Yes | No | No | No | Yes |
147
164
 
148
165
  Image, PDF, text-file, and audio inputs for text requests vary separately from output modalities. Provider APIs may also impose model-specific limits. See the [provider overview](https://batchwork.ajanraj.com/docs/providers) for input support, submission transport, credentials, and restrictions.
149
166
 
@@ -165,7 +182,7 @@ The base package does not import or require `upstash-redis`.
165
182
  - [Configuration](https://batchwork.ajanraj.com/docs/configuration)
166
183
  - [Jobs](https://batchwork.ajanraj.com/docs/guides/jobs)
167
184
  - [Results](https://batchwork.ajanraj.com/docs/guides/results)
168
- - [Text, embeddings, and images](https://batchwork.ajanraj.com/docs/modalities/text)
185
+ - [Text, embeddings, and other modalities](https://batchwork.ajanraj.com/docs/modalities/text)
169
186
  - [Provider overview](https://batchwork.ajanraj.com/docs/providers)
170
187
  - [Polling and webhooks](https://batchwork.ajanraj.com/docs/guides/server)
171
188
  - [Stores](https://batchwork.ajanraj.com/docs/guides/stores)
@@ -2,10 +2,10 @@
2
2
 
3
3
  ![Batchwork — one typed API for provider-native AI batch jobs](docs/public/og-image.png)
4
4
 
5
- Unified async batch API for OpenAI, Anthropic, Google Gemini, Groq, Mistral, Together AI, and xAI. Providers price eligible batch requests up to 50% below standard synchronous calls, and Batchwork gives you that pricing through one typed Python interface and one CLI. It handles provider-specific serialization, submission, polling, and result parsing so you do not have to. Pricing and eligibility remain provider- and model-specific.
5
+ Unified async batch API for OpenAI, Azure OpenAI, Anthropic, Google Gemini, Groq, Mistral, Together AI, and xAI. Providers price eligible batch requests up to 50% below standard synchronous calls, and Batchwork gives you that pricing through one typed Python interface and one CLI. It handles provider-specific serialization, submission, polling, and result parsing so you do not have to. Pricing and eligibility remain provider- and model-specific.
6
6
 
7
7
  - One typed API for provider-native batch jobs
8
- - Text, embedding, and image workloads
8
+ - Text, embedding, image, image-edit, moderation, transcription, translation, and video workloads
9
9
  - Normalized jobs, results, usage, and errors
10
10
  - Messages, tools, structured content, and remote media
11
11
  - Polling, persistent stores, and signed webhooks
@@ -97,21 +97,38 @@ asyncio.run(main())
97
97
 
98
98
  Submitting returns a `BatchJob` immediately. Provider processing is asynchronous and may take minutes or, depending on the provider and workload, up to 24 hours.
99
99
 
100
+ Beyond text, the same client covers seven more modalities — for example hosted-audio transcription:
101
+
102
+ ```python
103
+ from batchwork import BatchTranscriptionRequest
104
+
105
+ job = await client.batch_transcriptions(
106
+ model="groq/whisper-large-v3",
107
+ requests=[
108
+ BatchTranscriptionRequest(
109
+ custom_id="call-1",
110
+ audio_url="https://example.com/call-1.mp3",
111
+ )
112
+ ],
113
+ )
114
+ ```
115
+
100
116
  Models use `provider/model` form. Results are correlated with requests through `custom_id`; provider output order is not guaranteed.
101
117
 
102
118
  ## Providers
103
119
 
104
120
  Output workloads supported by Batchwork:
105
121
 
106
- | Provider | Text | Embeddings | Image generation |
107
- | ------------- | ---- | ---------- | ---------------- |
108
- | OpenAI | Yes | Yes | Yes |
109
- | Anthropic | Yes | No | No |
110
- | Google Gemini | Yes | Yes | Yes |
111
- | Groq | Yes | No | No |
112
- | Mistral | Yes | Yes | No |
113
- | Together AI | Yes | No | No |
114
- | xAI | Yes | No | Yes |
122
+ | Provider | Text | Embeddings | Image generation | Image edits | Moderation | Transcription | Translation | Video |
123
+ | --- | --- | --- | --- | --- | --- | --- | --- | --- |
124
+ | OpenAI | Yes | Yes | Yes | Yes | Yes | No | No | No |
125
+ | Azure OpenAI | Yes | No | No | No | No | No | No | No |
126
+ | Anthropic | Yes | No | No | No | No | No | No | No |
127
+ | Google Gemini | Yes | Yes | Yes | No | No | No | No | No |
128
+ | Groq | Yes | No | No | No | No | Yes | Yes | No |
129
+ | Mistral | Yes | Yes | No | No | Yes | Yes | No | No |
130
+ | Together AI | Yes | No | No | No | No | Yes | Yes | No |
131
+ | xAI | Yes | No | Yes | Yes | No | No | No | Yes |
115
132
 
116
133
  Image, PDF, text-file, and audio inputs for text requests vary separately from output modalities. Provider APIs may also impose model-specific limits. See the [provider overview](https://batchwork.ajanraj.com/docs/providers) for input support, submission transport, credentials, and restrictions.
117
134
 
@@ -133,7 +150,7 @@ The base package does not import or require `upstash-redis`.
133
150
  - [Configuration](https://batchwork.ajanraj.com/docs/configuration)
134
151
  - [Jobs](https://batchwork.ajanraj.com/docs/guides/jobs)
135
152
  - [Results](https://batchwork.ajanraj.com/docs/guides/results)
136
- - [Text, embeddings, and images](https://batchwork.ajanraj.com/docs/modalities/text)
153
+ - [Text, embeddings, and other modalities](https://batchwork.ajanraj.com/docs/modalities/text)
137
154
  - [Provider overview](https://batchwork.ajanraj.com/docs/providers)
138
155
  - [Polling and webhooks](https://batchwork.ajanraj.com/docs/guides/server)
139
156
  - [Stores](https://batchwork.ajanraj.com/docs/guides/stores)
@@ -0,0 +1,98 @@
1
+ [build-system]
2
+ requires = ["uv_build>=0.11.29,<0.12"]
3
+ build-backend = "uv_build"
4
+
5
+ [project]
6
+ name = "batchwork-ai"
7
+ version = "0.3.0"
8
+ description = "Unified async batch API for AI providers"
9
+ readme = "README.md"
10
+ requires-python = ">=3.11"
11
+ license = "MIT"
12
+ license-files = ["LICENSE"]
13
+ keywords = [
14
+ "ai",
15
+ "anthropic",
16
+ "batch",
17
+ "gemini",
18
+ "llm",
19
+ "openai",
20
+ ]
21
+ classifiers = [
22
+ "Development Status :: 3 - Alpha",
23
+ "Framework :: AsyncIO",
24
+ "Intended Audience :: Developers",
25
+ "Programming Language :: Python :: 3",
26
+ "Programming Language :: Python :: 3.11",
27
+ "Programming Language :: Python :: 3.12",
28
+ "Programming Language :: Python :: 3.13",
29
+ "Programming Language :: Python :: 3.14",
30
+ "Typing :: Typed",
31
+ ]
32
+ dependencies = [
33
+ "click>=8.4,<9",
34
+ "httpcore>=1,<2",
35
+ "httpx>=0.28,<1",
36
+ "pydantic>=2.11,<3",
37
+ ]
38
+
39
+ [[project.authors]]
40
+ name = "Ajanraj"
41
+ email = "hey@ajanraj.com"
42
+
43
+ [[project.maintainers]]
44
+ name = "Ajanraj"
45
+ email = "hey@ajanraj.com"
46
+
47
+ [project.scripts]
48
+ batchwork = "batchwork.cli:main"
49
+
50
+ [project.optional-dependencies]
51
+ redis = ["upstash-redis>=1.4,<2"]
52
+
53
+ [project.urls]
54
+ Documentation = "https://batchwork.ajanraj.com"
55
+ Issues = "https://github.com/ajanraj/batchwork-ai/issues"
56
+ Repository = "https://github.com/ajanraj/batchwork-ai"
57
+
58
+ [dependency-groups]
59
+ dev = [
60
+ "jsonschema>=4.25,<5",
61
+ "pytest>=8.4,<9",
62
+ "pytest-asyncio>=1,<2",
63
+ "pytest-cov>=6.2,<7",
64
+ "ruff>=0.12,<1",
65
+ "twine>=6.1,<7",
66
+ "ty==0.0.59",
67
+ ]
68
+
69
+ [tool.uv.build-backend]
70
+ module-name = "batchwork"
71
+ module-root = "src"
72
+
73
+ [tool.pytest.ini_options]
74
+ addopts = "-q"
75
+ asyncio_mode = "auto"
76
+ testpaths = ["tests"]
77
+ markers = [
78
+ "live: requires real provider credentials",
79
+ "redis: requires Upstash Redis credentials",
80
+ ]
81
+
82
+ [tool.ruff]
83
+ line-length = 100
84
+ target-version = "py311"
85
+
86
+ [tool.ruff.lint]
87
+ select = [
88
+ "E",
89
+ "F",
90
+ "I",
91
+ "UP",
92
+ "B",
93
+ "ASYNC",
94
+ "RUF",
95
+ ]
96
+
97
+ [tool.ty.src]
98
+ include = ["src"]
@@ -4,7 +4,7 @@ build-backend = "uv_build"
4
4
 
5
5
  [project]
6
6
  name = "batchwork-ai"
7
- version = "0.2.3"
7
+ version = "0.3.0"
8
8
  description = "Unified async batch API for AI providers"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -57,8 +57,15 @@ from .types import (
57
57
  BatchEmbeddingRequestSettings,
58
58
  BatchImage,
59
59
  BatchImageDefaults,
60
+ BatchImageEditDefaults,
61
+ BatchImageEditRequest,
62
+ BatchImageFileRef,
63
+ BatchImageRef,
60
64
  BatchImageRequest,
65
+ BatchImageUrlRef,
61
66
  BatchLimits,
67
+ BatchModeration,
68
+ BatchModerationRequest,
62
69
  BatchProvider,
63
70
  BatchRef,
64
71
  BatchRequest,
@@ -69,7 +76,15 @@ from .types import (
69
76
  BatchResultStatus,
70
77
  BatchSnapshot,
71
78
  BatchStatus,
79
+ BatchTranscriptionDefaults,
80
+ BatchTranscriptionRequest,
81
+ BatchTranscriptionSegment,
82
+ BatchTranslationDefaults,
83
+ BatchTranslationRequest,
72
84
  BatchUsage,
85
+ BatchVideo,
86
+ BatchVideoDefaults,
87
+ BatchVideoRequest,
73
88
  ContentToolOutput,
74
89
  CustomPart,
75
90
  DeprecatedToolOutputFileDataPart,
@@ -147,9 +162,16 @@ __all__ = [
147
162
  "BatchEmbeddingRequestSettings",
148
163
  "BatchImage",
149
164
  "BatchImageDefaults",
165
+ "BatchImageEditDefaults",
166
+ "BatchImageEditRequest",
167
+ "BatchImageFileRef",
168
+ "BatchImageRef",
150
169
  "BatchImageRequest",
170
+ "BatchImageUrlRef",
151
171
  "BatchJob",
152
172
  "BatchLimits",
173
+ "BatchModeration",
174
+ "BatchModerationRequest",
153
175
  "BatchPoller",
154
176
  "BatchProvider",
155
177
  "BatchRef",
@@ -164,7 +186,15 @@ __all__ = [
164
186
  "BatchStatus",
165
187
  "BatchStore",
166
188
  "BatchTimeoutError",
189
+ "BatchTranscriptionDefaults",
190
+ "BatchTranscriptionRequest",
191
+ "BatchTranscriptionSegment",
192
+ "BatchTranslationDefaults",
193
+ "BatchTranslationRequest",
167
194
  "BatchUsage",
195
+ "BatchVideo",
196
+ "BatchVideoDefaults",
197
+ "BatchVideoRequest",
168
198
  "BatchWebhookEvent",
169
199
  "Batchwork",
170
200
  "BatchworkError",
@@ -16,3 +16,4 @@ MAX_AGGREGATE_RESULTS_BYTES = 1024 * 1024 * 1024
16
16
  LARGE_BATCH_REQUESTS = 10_000
17
17
  LARGE_BATCH_UPLOAD_BYTES = 50 * 1024 * 1024
18
18
  LARGE_BATCH_IMAGES = 100
19
+ LARGE_BATCH_VIDEOS = 20