runapi-core 0.8.3__tar.gz → 0.9.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.
- {runapi_core-0.8.3 → runapi_core-0.9.0}/PKG-INFO +3 -3
- {runapi_core-0.8.3 → runapi_core-0.9.0}/README.md +1 -1
- {runapi_core-0.8.3 → runapi_core-0.9.0}/pyproject.toml +1 -1
- {runapi_core-0.8.3 → runapi_core-0.9.0}/src/runapi/core/__init__.py +2 -8
- {runapi_core-0.8.3 → runapi_core-0.9.0}/src/runapi/core/contract_gen.py +35 -5
- {runapi_core-0.8.3 → runapi_core-0.9.0}/src/runapi/core/models.py +8 -20
- runapi_core-0.9.0/src/runapi/core/version.py +1 -0
- {runapi_core-0.8.3 → runapi_core-0.9.0}/tests/test_models.py +29 -12
- {runapi_core-0.8.3 → runapi_core-0.9.0}/tests/test_resource.py +17 -33
- runapi_core-0.8.3/src/runapi/core/version.py +0 -1
- {runapi_core-0.8.3 → runapi_core-0.9.0}/src/runapi/core/account.py +0 -0
- {runapi_core-0.8.3 → runapi_core-0.9.0}/src/runapi/core/auth.py +0 -0
- {runapi_core-0.8.3 → runapi_core-0.9.0}/src/runapi/core/config.py +0 -0
- {runapi_core-0.8.3 → runapi_core-0.9.0}/src/runapi/core/constants.py +0 -0
- {runapi_core-0.8.3 → runapi_core-0.9.0}/src/runapi/core/errors.py +0 -0
- {runapi_core-0.8.3 → runapi_core-0.9.0}/src/runapi/core/files.py +0 -0
- {runapi_core-0.8.3 → runapi_core-0.9.0}/src/runapi/core/http_client.py +0 -0
- {runapi_core-0.8.3 → runapi_core-0.9.0}/src/runapi/core/multipart.py +0 -0
- {runapi_core-0.8.3 → runapi_core-0.9.0}/src/runapi/core/options.py +0 -0
- {runapi_core-0.8.3 → runapi_core-0.9.0}/src/runapi/core/polling.py +0 -0
- {runapi_core-0.8.3 → runapi_core-0.9.0}/src/runapi/core/pricing.py +0 -0
- {runapi_core-0.8.3 → runapi_core-0.9.0}/src/runapi/core/provider_client.py +0 -0
- {runapi_core-0.8.3 → runapi_core-0.9.0}/src/runapi/core/py.typed +0 -0
- {runapi_core-0.8.3 → runapi_core-0.9.0}/src/runapi/core/resource.py +0 -0
- {runapi_core-0.8.3 → runapi_core-0.9.0}/src/runapi/core/response.py +0 -0
- {runapi_core-0.8.3 → runapi_core-0.9.0}/src/runapi/core/uploads.py +0 -0
- {runapi_core-0.8.3 → runapi_core-0.9.0}/tests/test_account.py +0 -0
- {runapi_core-0.8.3 → runapi_core-0.9.0}/tests/test_auth.py +0 -0
- {runapi_core-0.8.3 → runapi_core-0.9.0}/tests/test_config.py +0 -0
- {runapi_core-0.8.3 → runapi_core-0.9.0}/tests/test_errors.py +0 -0
- {runapi_core-0.8.3 → runapi_core-0.9.0}/tests/test_files.py +0 -0
- {runapi_core-0.8.3 → runapi_core-0.9.0}/tests/test_http_client.py +0 -0
- {runapi_core-0.8.3 → runapi_core-0.9.0}/tests/test_polling.py +0 -0
- {runapi_core-0.8.3 → runapi_core-0.9.0}/tests/test_pricing.py +0 -0
- {runapi_core-0.8.3 → runapi_core-0.9.0}/tests/test_uploads.py +0 -0
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: runapi-core
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.9.0
|
|
4
4
|
Summary: RunAPI core SDK for JavaScript, Python, Ruby, Go, Java, and PHP
|
|
5
5
|
Project-URL: Homepage, https://runapi.ai/models
|
|
6
6
|
Project-URL: Documentation, https://runapi.ai/docs/resources/sdks
|
|
7
7
|
Project-URL: Source, https://github.com/runapi-ai/core-sdk
|
|
8
8
|
Project-URL: Issues, https://github.com/runapi-ai/core-sdk/issues
|
|
9
9
|
Project-URL: Changelog, https://github.com/runapi-ai/core-sdk/blob/main/CHANGELOG.md
|
|
10
|
-
Project-URL: Release Notes, https://github.com/runapi-ai/core-sdk/releases/tag/python%2Fv0.
|
|
10
|
+
Project-URL: Release Notes, https://github.com/runapi-ai/core-sdk/releases/tag/python%2Fv0.9.0
|
|
11
11
|
Author-email: RunAPI <contact@runapi.ai>
|
|
12
12
|
License-Expression: Apache-2.0
|
|
13
13
|
Keywords: api,core,golang,gradle,java,maven,pypi,python,ruby,runapi,runapi-ai,sdk,typescript
|
|
@@ -134,7 +134,7 @@ quote = client.pricing.create_quote(
|
|
|
134
134
|
)
|
|
135
135
|
```
|
|
136
136
|
|
|
137
|
-
Task
|
|
137
|
+
Completed Task query and webhook envelopes expose `usage.cost` as a float USD amount for that Task. Create, processing, and failed envelopes omit `usage`. The value is the recorded settlement for that Task and is never recalculated from the current price schedule.
|
|
138
138
|
|
|
139
139
|
## License
|
|
140
140
|
|
|
@@ -117,7 +117,7 @@ quote = client.pricing.create_quote(
|
|
|
117
117
|
)
|
|
118
118
|
```
|
|
119
119
|
|
|
120
|
-
Task
|
|
120
|
+
Completed Task query and webhook envelopes expose `usage.cost` as a float USD amount for that Task. Create, processing, and failed envelopes omit `usage`. The value is the recorded settlement for that Task and is never recalculated from the current price schedule.
|
|
121
121
|
|
|
122
122
|
## License
|
|
123
123
|
|
|
@@ -19,7 +19,7 @@ Documentation = "https://runapi.ai/docs/resources/sdks"
|
|
|
19
19
|
Source = "https://github.com/runapi-ai/core-sdk"
|
|
20
20
|
Issues = "https://github.com/runapi-ai/core-sdk/issues"
|
|
21
21
|
Changelog = "https://github.com/runapi-ai/core-sdk/blob/main/CHANGELOG.md"
|
|
22
|
-
"Release Notes" = "https://github.com/runapi-ai/core-sdk/releases/tag/python%2Fv0.
|
|
22
|
+
"Release Notes" = "https://github.com/runapi-ai/core-sdk/releases/tag/python%2Fv0.9.0"
|
|
23
23
|
|
|
24
24
|
[tool.hatch.version]
|
|
25
25
|
path = "src/runapi/core/version.py"
|
|
@@ -29,14 +29,11 @@ from .files import DeletedFile, FileList, FileObject, FilesClient, UploadRespons
|
|
|
29
29
|
from .http_client import HttpClient
|
|
30
30
|
from .models import (
|
|
31
31
|
BaseModel,
|
|
32
|
-
BillingRefund,
|
|
33
|
-
BillingReservation,
|
|
34
|
-
BillingSettlement,
|
|
35
32
|
DynamicModel,
|
|
36
|
-
TaskBillingFacts,
|
|
37
33
|
TaskResult,
|
|
38
34
|
TaskResultResponse,
|
|
39
35
|
TaskResponse,
|
|
36
|
+
TaskUsage,
|
|
40
37
|
optional,
|
|
41
38
|
required,
|
|
42
39
|
)
|
|
@@ -86,10 +83,7 @@ __all__ = [
|
|
|
86
83
|
"TaskResponse",
|
|
87
84
|
"TaskResult",
|
|
88
85
|
"TaskResultResponse",
|
|
89
|
-
"
|
|
90
|
-
"BillingSettlement",
|
|
91
|
-
"BillingRefund",
|
|
92
|
-
"TaskBillingFacts",
|
|
86
|
+
"TaskUsage",
|
|
93
87
|
"required",
|
|
94
88
|
"optional",
|
|
95
89
|
"MultipartBody",
|
|
@@ -2109,11 +2109,31 @@ CONTRACT = {
|
|
|
2109
2109
|
"suno/remaster-audio": {
|
|
2110
2110
|
"models": ["suno-v4", "suno-v4.5", "suno-v4.5-plus", "suno-v5", "suno-v5.5"],
|
|
2111
2111
|
"fields_by_model": {
|
|
2112
|
-
"suno-v4": {
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2112
|
+
"suno-v4": {
|
|
2113
|
+
"variation_category": {
|
|
2114
|
+
"enum": ["subtle", "normal", "high"]
|
|
2115
|
+
}
|
|
2116
|
+
},
|
|
2117
|
+
"suno-v4.5": {
|
|
2118
|
+
"variation_category": {
|
|
2119
|
+
"enum": ["subtle", "normal", "high"]
|
|
2120
|
+
}
|
|
2121
|
+
},
|
|
2122
|
+
"suno-v4.5-plus": {
|
|
2123
|
+
"variation_category": {
|
|
2124
|
+
"enum": ["subtle", "normal", "high"]
|
|
2125
|
+
}
|
|
2126
|
+
},
|
|
2127
|
+
"suno-v5": {
|
|
2128
|
+
"variation_category": {
|
|
2129
|
+
"enum": ["subtle", "normal", "high"]
|
|
2130
|
+
}
|
|
2131
|
+
},
|
|
2132
|
+
"suno-v5.5": {
|
|
2133
|
+
"variation_category": {
|
|
2134
|
+
"enum": ["subtle", "normal", "high"]
|
|
2135
|
+
}
|
|
2136
|
+
}
|
|
2117
2137
|
}
|
|
2118
2138
|
},
|
|
2119
2139
|
"suno/replace-section": {
|
|
@@ -2322,6 +2342,16 @@ CONTRACT = {
|
|
|
2322
2342
|
}
|
|
2323
2343
|
}
|
|
2324
2344
|
},
|
|
2345
|
+
"typesafe/system-one": {
|
|
2346
|
+
"models": ["jev-latest"],
|
|
2347
|
+
"fields_by_model": {
|
|
2348
|
+
"jev-latest": {
|
|
2349
|
+
"model": {
|
|
2350
|
+
"enum": ["jev-latest"]
|
|
2351
|
+
}
|
|
2352
|
+
}
|
|
2353
|
+
}
|
|
2354
|
+
},
|
|
2325
2355
|
"veo-3-1/extend-video": {
|
|
2326
2356
|
"models": [],
|
|
2327
2357
|
"fields_by_model": {
|
|
@@ -263,7 +263,7 @@ class TaskResponse(BaseModel):
|
|
|
263
263
|
id = optional(str)
|
|
264
264
|
status = optional(str)
|
|
265
265
|
error = optional(str)
|
|
266
|
-
|
|
266
|
+
usage = optional(lambda: TaskUsage)
|
|
267
267
|
|
|
268
268
|
|
|
269
269
|
class TaskResultResponse(BaseModel):
|
|
@@ -275,28 +275,16 @@ class TaskResultResponse(BaseModel):
|
|
|
275
275
|
body = optional()
|
|
276
276
|
|
|
277
277
|
|
|
278
|
-
class TaskResult(
|
|
278
|
+
class TaskResult(BaseModel):
|
|
279
279
|
"""The account-scoped Task Result resource returned from an opaque Location."""
|
|
280
280
|
|
|
281
|
+
Status = TaskResponse.Status
|
|
282
|
+
|
|
281
283
|
id = required(str)
|
|
282
|
-
status = required(str, enum=lambda:
|
|
284
|
+
status = required(str, enum=lambda: TaskResult.Status.ALL)
|
|
285
|
+
error = optional(str)
|
|
283
286
|
response = optional(lambda: TaskResultResponse)
|
|
284
287
|
|
|
285
288
|
|
|
286
|
-
class
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
class BillingSettlement(BaseModel):
|
|
291
|
-
charged_amount_cents = required(int)
|
|
292
|
-
amount_micro_cents = required(int)
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
class BillingRefund(BaseModel):
|
|
296
|
-
refunded_at = required(str)
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
class TaskBillingFacts(BaseModel):
|
|
300
|
-
reservation = optional(BillingReservation)
|
|
301
|
-
settlement = optional(BillingSettlement)
|
|
302
|
-
refund = optional(BillingRefund)
|
|
289
|
+
class TaskUsage(BaseModel):
|
|
290
|
+
cost = required(float)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.9.0"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import pytest
|
|
2
2
|
|
|
3
|
-
from runapi.core import BaseModel, DynamicModel,
|
|
3
|
+
from runapi.core import BaseModel, DynamicModel, TaskResult, TaskResponse, TaskUsage, optional, required
|
|
4
4
|
from runapi.core.errors import ValidationError
|
|
5
5
|
|
|
6
6
|
|
|
@@ -34,7 +34,7 @@ def test_required_field_missing_raises():
|
|
|
34
34
|
|
|
35
35
|
|
|
36
36
|
def test_item_and_dot_access():
|
|
37
|
-
model = Sample({"id": "abc", "status": "completed"})
|
|
37
|
+
model = Sample({"id": "abc", "status": "completed", "usage": {"cost": 0.05}})
|
|
38
38
|
assert model["id"] == "abc"
|
|
39
39
|
assert model.status == "completed"
|
|
40
40
|
|
|
@@ -45,8 +45,7 @@ def test_coerces_nested_hashes_and_arrays():
|
|
|
45
45
|
"id": "abc",
|
|
46
46
|
"meta": {"count": 2},
|
|
47
47
|
"items": [{"name": "first"}],
|
|
48
|
-
"extra_field": {"nested": True}
|
|
49
|
-
}
|
|
48
|
+
"extra_field": {"nested": True}}
|
|
50
49
|
)
|
|
51
50
|
assert isinstance(model.meta, DynamicModel)
|
|
52
51
|
assert model.meta.count == 2
|
|
@@ -70,8 +69,8 @@ def test_to_dict_serializes_recursively():
|
|
|
70
69
|
|
|
71
70
|
|
|
72
71
|
def test_equality_with_dict():
|
|
73
|
-
model = Sample({"id": "abc", "status": "completed"})
|
|
74
|
-
assert model == {"id": "abc", "status": "completed"}
|
|
72
|
+
model = Sample({"id": "abc", "status": "completed", "usage": {"cost": 0.05}})
|
|
73
|
+
assert model == {"id": "abc", "status": "completed", "usage": {"cost": 0.05}}
|
|
75
74
|
|
|
76
75
|
|
|
77
76
|
def test_optional_absent_field_is_none():
|
|
@@ -119,14 +118,32 @@ def test_response_headers_stay_outside_serialized_body():
|
|
|
119
118
|
assert model.to_dict() == {"id": "abc"}
|
|
120
119
|
|
|
121
120
|
|
|
122
|
-
def
|
|
121
|
+
def test_task_response_coerces_typed_usage_and_preserves_unknown_fields():
|
|
123
122
|
response = TaskResponse(
|
|
124
123
|
{
|
|
125
124
|
"id": "task_1",
|
|
126
|
-
"
|
|
127
|
-
|
|
125
|
+
"status": "completed",
|
|
126
|
+
"usage": {"cost": 0.05, "future_fact": "retained"}}
|
|
128
127
|
)
|
|
129
128
|
|
|
130
|
-
assert isinstance(response.
|
|
131
|
-
assert response.
|
|
132
|
-
assert response.
|
|
129
|
+
assert isinstance(response.usage, TaskUsage)
|
|
130
|
+
assert response.usage.cost == 0.05
|
|
131
|
+
assert response.usage.future_fact == "retained"
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def test_task_result_preserves_public_status_constants_without_task_usage():
|
|
135
|
+
assert [
|
|
136
|
+
TaskResult.Status.PENDING,
|
|
137
|
+
TaskResult.Status.PROCESSING,
|
|
138
|
+
TaskResult.Status.COMPLETED,
|
|
139
|
+
TaskResult.Status.FAILED,
|
|
140
|
+
] == ["pending", "processing", "completed", "failed"]
|
|
141
|
+
|
|
142
|
+
result = TaskResult({"id": "task_1", "status": TaskResult.Status.COMPLETED})
|
|
143
|
+
assert result.status == "completed"
|
|
144
|
+
assert "usage" not in result.to_dict()
|
|
145
|
+
with pytest.raises(AttributeError):
|
|
146
|
+
_ = result.usage
|
|
147
|
+
|
|
148
|
+
with pytest.raises(ValidationError, match="Invalid status"):
|
|
149
|
+
TaskResult({"id": "task_1", "status": "unknown"})
|
|
@@ -91,10 +91,8 @@ INT_SCHEMA = {
|
|
|
91
91
|
"fields_by_model": {
|
|
92
92
|
"m": {
|
|
93
93
|
"duration_int": {"type": "integer", "min": 4, "max": 12},
|
|
94
|
-
"tolerance": {"type": "integer"}
|
|
95
|
-
|
|
96
|
-
},
|
|
97
|
-
}
|
|
94
|
+
"tolerance": {"type": "integer"}}
|
|
95
|
+
}}
|
|
98
96
|
|
|
99
97
|
|
|
100
98
|
def _run_validate(params):
|
|
@@ -130,10 +128,8 @@ def test_validate_functional_action_uses_underscore_fields():
|
|
|
130
128
|
"fields_by_model": {
|
|
131
129
|
"_": {
|
|
132
130
|
"prompt": {"required": True},
|
|
133
|
-
"mode": {"enum": ["fast", "quality"]}
|
|
134
|
-
|
|
135
|
-
},
|
|
136
|
-
}
|
|
131
|
+
"mode": {"enum": ["fast", "quality"]}}
|
|
132
|
+
}}
|
|
137
133
|
resource._validate_contract(schema, {"prompt": "hello", "mode": "fast"})
|
|
138
134
|
with pytest.raises(ValidationError, match="prompt is required"):
|
|
139
135
|
resource._validate_contract(schema, {"mode": "fast"})
|
|
@@ -164,10 +160,8 @@ def test_validate_array_item_count_constraints():
|
|
|
164
160
|
"models": ["m"],
|
|
165
161
|
"fields_by_model": {
|
|
166
162
|
"m": {
|
|
167
|
-
"reference_image_urls": {"min_items": 1, "max_items": 3}
|
|
168
|
-
|
|
169
|
-
},
|
|
170
|
-
}
|
|
163
|
+
"reference_image_urls": {"min_items": 1, "max_items": 3}}
|
|
164
|
+
}}
|
|
171
165
|
resource = SampleResource(FakeHttp())
|
|
172
166
|
|
|
173
167
|
with pytest.raises(ValidationError, match="^reference_image_urls must be an array$"):
|
|
@@ -187,8 +181,7 @@ def test_validate_contract_runs_rules_before_field_requirements():
|
|
|
187
181
|
schema = {
|
|
188
182
|
"models": ["m"],
|
|
189
183
|
"rules": [{"when": {"model": "m"}, "forbidden": ["source_task_id"]}],
|
|
190
|
-
"fields_by_model": {"m": {"source_image_urls": {"required": True}}}
|
|
191
|
-
}
|
|
184
|
+
"fields_by_model": {"m": {"source_image_urls": {"required": True}}}}
|
|
192
185
|
resource = SampleResource(FakeHttp())
|
|
193
186
|
with pytest.raises(ValidationError, match="source_task_id is not allowed when model is m"):
|
|
194
187
|
resource._validate_contract(schema, {"model": "m", "source_task_id": "src_1"})
|
|
@@ -196,7 +189,7 @@ def test_validate_contract_runs_rules_before_field_requirements():
|
|
|
196
189
|
|
|
197
190
|
def test_poll_recoerces_to_completed_class():
|
|
198
191
|
resource = SampleResource(FakeHttp())
|
|
199
|
-
response = TaskResponse({"id": "1", "status": "completed", "images": [{"url": "u"}]})
|
|
192
|
+
response = TaskResponse({"id": "1", "status": "completed", "usage": {"cost": 0.05}, "images": [{"url": "u"}]})
|
|
200
193
|
result = resource._poll_until_complete(lambda: response, PollingOptions(poll_interval=0, max_wait=1))
|
|
201
194
|
assert isinstance(result, CompletedResponse)
|
|
202
195
|
assert result.images[0].url == "u"
|
|
@@ -215,14 +208,12 @@ def test_run_hybrid_uses_opaque_location_and_decodes_completed_json(monkeypatch)
|
|
|
215
208
|
ApiResponse(
|
|
216
209
|
{
|
|
217
210
|
"id": "task_1",
|
|
218
|
-
"status": "completed",
|
|
211
|
+
"status": "completed", "usage": {"cost": 0.05},
|
|
219
212
|
"response": {
|
|
220
213
|
"status": 200,
|
|
221
214
|
"content_type": "application/json",
|
|
222
215
|
"headers": {"Location": "https://runapi.ai/result"},
|
|
223
|
-
"body": {"id": "task_1", "status": "completed", "prompts": ["short prompt"]}
|
|
224
|
-
},
|
|
225
|
-
}
|
|
216
|
+
"body": {"id": "task_1", "status": "completed", "usage": {"cost": 0.05}, "prompts": ["short prompt"]}}}
|
|
226
217
|
),
|
|
227
218
|
)
|
|
228
219
|
|
|
@@ -234,8 +225,7 @@ def test_run_hybrid_uses_opaque_location_and_decodes_completed_json(monkeypatch)
|
|
|
234
225
|
assert [call[:2] for call in http.calls] == [
|
|
235
226
|
("post", "/shorten"),
|
|
236
227
|
("get", "https://runapi.ai/api/v1/tasks/task_1"),
|
|
237
|
-
("get", "https://runapi.ai/api/v1/tasks/task_1")
|
|
238
|
-
]
|
|
228
|
+
("get", "https://runapi.ai/api/v1/tasks/task_1")]
|
|
239
229
|
assert slept == [3.0, 2.0]
|
|
240
230
|
|
|
241
231
|
|
|
@@ -248,7 +238,7 @@ def test_run_hybrid_honors_http_date_retry_after(monkeypatch):
|
|
|
248
238
|
http = FakeHttp(
|
|
249
239
|
ApiResponse({"id": "task_1", "status": "processing"}, {"Location": "/api/v1/tasks/task_1", "Retry-After": initial_retry_after}, status_code=202),
|
|
250
240
|
ApiResponse({"id": "task_1", "status": "processing"}, {"Retry-After": polling_retry_after}),
|
|
251
|
-
ApiResponse({"id": "task_1", "status": "completed", "response": {"status": 200, "content_type": "application/json", "headers": {}, "body": {"id": "task_1", "status": "completed", "prompts": ["short prompt"]}}}),
|
|
241
|
+
ApiResponse({"id": "task_1", "status": "completed", "usage": {"cost": 0.05}, "response": {"status": 200, "content_type": "application/json", "headers": {}, "body": {"id": "task_1", "status": "completed", "usage": {"cost": 0.05}, "prompts": ["short prompt"]}}}),
|
|
252
242
|
)
|
|
253
243
|
|
|
254
244
|
HybridResource(http)._run_hybrid("post", "/shorten", {"prompt": "long"})
|
|
@@ -273,14 +263,12 @@ def test_run_hybrid_follows_a_real_http_stub_and_reuses_generated_key(monkeypatc
|
|
|
273
263
|
200,
|
|
274
264
|
json={
|
|
275
265
|
"id": "task_1",
|
|
276
|
-
"status": "completed",
|
|
266
|
+
"status": "completed", "usage": {"cost": 0.05},
|
|
277
267
|
"response": {
|
|
278
268
|
"status": 200,
|
|
279
269
|
"content_type": "application/json",
|
|
280
270
|
"headers": {},
|
|
281
|
-
"body": {"id": "task_1", "status": "completed", "prompts": ["short prompt"]},
|
|
282
|
-
},
|
|
283
|
-
},
|
|
271
|
+
"body": {"id": "task_1", "status": "completed", "usage": {"cost": 0.05}, "prompts": ["short prompt"]}}},
|
|
284
272
|
)
|
|
285
273
|
|
|
286
274
|
http = HttpClient(
|
|
@@ -383,14 +371,12 @@ def test_subscribe_returns_text_srt_and_vtt_without_coercing_to_bytes(monkeypatc
|
|
|
383
371
|
ApiResponse(
|
|
384
372
|
{
|
|
385
373
|
"id": "task_text",
|
|
386
|
-
"status": "completed",
|
|
374
|
+
"status": "completed", "usage": {"cost": 0.05},
|
|
387
375
|
"response": {
|
|
388
376
|
"status": 200,
|
|
389
377
|
"content_type": "text/vtt; charset=utf-8",
|
|
390
378
|
"headers": {},
|
|
391
|
-
"body": "WEBVTT\n\n00:00.000 --> 00:01.000\nHello"
|
|
392
|
-
},
|
|
393
|
-
}
|
|
379
|
+
"body": "WEBVTT\n\n00:00.000 --> 00:01.000\nHello"}}
|
|
394
380
|
)
|
|
395
381
|
)
|
|
396
382
|
|
|
@@ -410,9 +396,7 @@ def test_subscribe_maps_failed_task_checkpoint_to_public_error(monkeypatch):
|
|
|
410
396
|
"status": 422,
|
|
411
397
|
"content_type": "application/json",
|
|
412
398
|
"headers": {},
|
|
413
|
-
"body": {"error": "Prompt rejected"}
|
|
414
|
-
},
|
|
415
|
-
}
|
|
399
|
+
"body": {"error": "Prompt rejected"}}}
|
|
416
400
|
)
|
|
417
401
|
)
|
|
418
402
|
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.8.3"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|