diffio 0.1.41__tar.gz → 0.1.43__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.
- {diffio-0.1.41/src/diffio.egg-info → diffio-0.1.43}/PKG-INFO +7 -1
- {diffio-0.1.41 → diffio-0.1.43}/README.md +6 -0
- {diffio-0.1.41 → diffio-0.1.43}/pyproject.toml +1 -1
- {diffio-0.1.41 → diffio-0.1.43}/src/diffio/__init__.py +1 -1
- {diffio-0.1.41 → diffio-0.1.43}/src/diffio/client.py +7 -1
- {diffio-0.1.41 → diffio-0.1.43}/src/diffio/types.py +11 -2
- {diffio-0.1.41 → diffio-0.1.43/src/diffio.egg-info}/PKG-INFO +7 -1
- {diffio-0.1.41 → diffio-0.1.43}/tests/test_client.py +150 -1
- {diffio-0.1.41 → diffio-0.1.43}/LICENSE +0 -0
- {diffio-0.1.41 → diffio-0.1.43}/setup.cfg +0 -0
- {diffio-0.1.41 → diffio-0.1.43}/src/diffio/errors.py +0 -0
- {diffio-0.1.41 → diffio-0.1.43}/src/diffio/testing.py +0 -0
- {diffio-0.1.41 → diffio-0.1.43}/src/diffio.egg-info/SOURCES.txt +0 -0
- {diffio-0.1.41 → diffio-0.1.43}/src/diffio.egg-info/dependency_links.txt +0 -0
- {diffio-0.1.41 → diffio-0.1.43}/src/diffio.egg-info/requires.txt +0 -0
- {diffio-0.1.41 → diffio-0.1.43}/src/diffio.egg-info/top_level.txt +0 -0
- {diffio-0.1.41 → diffio-0.1.43}/tests/test_emulator_e2e.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: diffio
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.43
|
|
4
4
|
Summary: Python SDK for the Diffio API.
|
|
5
5
|
Author: Diffio
|
|
6
6
|
License: MIT
|
|
@@ -89,11 +89,17 @@ generation = client.create_generation(
|
|
|
89
89
|
apiProjectId=project.apiProjectId,
|
|
90
90
|
model="diffio-3.5",
|
|
91
91
|
sampling={"steps": 12, "guidance": 1.5},
|
|
92
|
+
idempotencyKey="restore-job-2026-001",
|
|
92
93
|
)
|
|
93
94
|
|
|
94
95
|
print(generation.generationId)
|
|
96
|
+
print(generation.idempotentReplay)
|
|
95
97
|
```
|
|
96
98
|
|
|
99
|
+
Use one stable `idempotencyKey` for every retry of the same logical generation request.
|
|
100
|
+
The response's optional `idempotentReplay` value is `True` when the API returns the
|
|
101
|
+
result of an earlier request with that key. Use a new key for a different generation.
|
|
102
|
+
|
|
97
103
|
## Audio isolation helper
|
|
98
104
|
|
|
99
105
|
```py
|
|
@@ -61,11 +61,17 @@ generation = client.create_generation(
|
|
|
61
61
|
apiProjectId=project.apiProjectId,
|
|
62
62
|
model="diffio-3.5",
|
|
63
63
|
sampling={"steps": 12, "guidance": 1.5},
|
|
64
|
+
idempotencyKey="restore-job-2026-001",
|
|
64
65
|
)
|
|
65
66
|
|
|
66
67
|
print(generation.generationId)
|
|
68
|
+
print(generation.idempotentReplay)
|
|
67
69
|
```
|
|
68
70
|
|
|
71
|
+
Use one stable `idempotencyKey` for every retry of the same logical generation request.
|
|
72
|
+
The response's optional `idempotentReplay` value is `True` when the API returns the
|
|
73
|
+
result of an earlier request with that key. Use a new key for a different generation.
|
|
74
|
+
|
|
69
75
|
## Audio isolation helper
|
|
70
76
|
|
|
71
77
|
```py
|
|
@@ -36,7 +36,6 @@ API_PREFIX = "v1"
|
|
|
36
36
|
MODEL_ENDPOINTS = {
|
|
37
37
|
"diffio-2": "diffio-2.0-generation",
|
|
38
38
|
"diffio-2-flash": "diffio-2.0-flash-generation",
|
|
39
|
-
"diffio-3": "diffio-3.0-generation",
|
|
40
39
|
"diffio-3.4": "diffio-3.4-generation",
|
|
41
40
|
"diffio-3.5": "diffio-3.5-generation",
|
|
42
41
|
}
|
|
@@ -309,6 +308,7 @@ class DiffioClient:
|
|
|
309
308
|
model="diffio-2",
|
|
310
309
|
sampling=None,
|
|
311
310
|
params=None,
|
|
311
|
+
idempotencyKey=None,
|
|
312
312
|
requestOptions=None,
|
|
313
313
|
):
|
|
314
314
|
endpoint = MODEL_ENDPOINTS.get(model)
|
|
@@ -320,6 +320,8 @@ class DiffioClient:
|
|
|
320
320
|
payload["sampling"] = sampling
|
|
321
321
|
if params:
|
|
322
322
|
payload["params"] = params
|
|
323
|
+
if idempotencyKey is not None:
|
|
324
|
+
payload["idempotencyKey"] = idempotencyKey
|
|
323
325
|
|
|
324
326
|
response = self._request("POST", endpoint, json_payload=payload, requestOptions=requestOptions)
|
|
325
327
|
return CreateGenerationResponse.from_dict(response)
|
|
@@ -833,6 +835,7 @@ class GenerationsClient:
|
|
|
833
835
|
model="diffio-2",
|
|
834
836
|
sampling=None,
|
|
835
837
|
params=None,
|
|
838
|
+
idempotencyKey=None,
|
|
836
839
|
requestOptions=None,
|
|
837
840
|
):
|
|
838
841
|
return self._parent.create_generation(
|
|
@@ -840,6 +843,7 @@ class GenerationsClient:
|
|
|
840
843
|
model=model,
|
|
841
844
|
sampling=sampling,
|
|
842
845
|
params=params,
|
|
846
|
+
idempotencyKey=idempotencyKey,
|
|
843
847
|
requestOptions=requestOptions,
|
|
844
848
|
)
|
|
845
849
|
|
|
@@ -945,6 +949,7 @@ class GenerationsClient:
|
|
|
945
949
|
model="diffio-2",
|
|
946
950
|
sampling=None,
|
|
947
951
|
params=None,
|
|
952
|
+
idempotencyKey=None,
|
|
948
953
|
pollInterval=2.0,
|
|
949
954
|
timeout=600.0,
|
|
950
955
|
onProgress=None,
|
|
@@ -958,6 +963,7 @@ class GenerationsClient:
|
|
|
958
963
|
model=model,
|
|
959
964
|
sampling=sampling,
|
|
960
965
|
params=params,
|
|
966
|
+
idempotencyKey=idempotencyKey,
|
|
961
967
|
requestOptions=requestOptions,
|
|
962
968
|
)
|
|
963
969
|
progress = self.wait_for_complete(
|
|
@@ -76,11 +76,19 @@ class ListProjectsResponse:
|
|
|
76
76
|
|
|
77
77
|
|
|
78
78
|
class CreateGenerationResponse:
|
|
79
|
-
def __init__(
|
|
79
|
+
def __init__(
|
|
80
|
+
self,
|
|
81
|
+
generationId,
|
|
82
|
+
apiProjectId,
|
|
83
|
+
modelKey,
|
|
84
|
+
status,
|
|
85
|
+
idempotentReplay=None,
|
|
86
|
+
):
|
|
80
87
|
self.generationId = generationId
|
|
81
88
|
self.apiProjectId = apiProjectId
|
|
82
89
|
self.modelKey = modelKey
|
|
83
90
|
self.status = status
|
|
91
|
+
self.idempotentReplay = idempotentReplay
|
|
84
92
|
|
|
85
93
|
@classmethod
|
|
86
94
|
def from_dict(cls, data):
|
|
@@ -89,6 +97,7 @@ class CreateGenerationResponse:
|
|
|
89
97
|
apiProjectId=data["apiProjectId"],
|
|
90
98
|
modelKey=data["modelKey"],
|
|
91
99
|
status=data["status"],
|
|
100
|
+
idempotentReplay=data.get("idempotentReplay"),
|
|
92
101
|
)
|
|
93
102
|
|
|
94
103
|
|
|
@@ -419,7 +428,7 @@ class AudioIsolationResult:
|
|
|
419
428
|
self.generation = generation
|
|
420
429
|
|
|
421
430
|
|
|
422
|
-
ModelKey = ("diffio-2", "diffio-2-flash", "diffio-3
|
|
431
|
+
ModelKey = ("diffio-2", "diffio-2-flash", "diffio-3.4", "diffio-3.5")
|
|
423
432
|
DownloadType = ("audio", "mp3", "video", "transcript")
|
|
424
433
|
WebhookMode = ("test", "live")
|
|
425
434
|
WebhookEventType = (
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: diffio
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.43
|
|
4
4
|
Summary: Python SDK for the Diffio API.
|
|
5
5
|
Author: Diffio
|
|
6
6
|
License: MIT
|
|
@@ -89,11 +89,17 @@ generation = client.create_generation(
|
|
|
89
89
|
apiProjectId=project.apiProjectId,
|
|
90
90
|
model="diffio-3.5",
|
|
91
91
|
sampling={"steps": 12, "guidance": 1.5},
|
|
92
|
+
idempotencyKey="restore-job-2026-001",
|
|
92
93
|
)
|
|
93
94
|
|
|
94
95
|
print(generation.generationId)
|
|
96
|
+
print(generation.idempotentReplay)
|
|
95
97
|
```
|
|
96
98
|
|
|
99
|
+
Use one stable `idempotencyKey` for every retry of the same logical generation request.
|
|
100
|
+
The response's optional `idempotentReplay` value is `True` when the API returns the
|
|
101
|
+
result of an earlier request with that key. Use a new key for a different generation.
|
|
102
|
+
|
|
97
103
|
## Audio isolation helper
|
|
98
104
|
|
|
99
105
|
```py
|
|
@@ -5,7 +5,8 @@ from pathlib import Path
|
|
|
5
5
|
import httpx
|
|
6
6
|
import pytest
|
|
7
7
|
|
|
8
|
-
from diffio import DiffioClient
|
|
8
|
+
from diffio import DiffioClient, ModelKey
|
|
9
|
+
from diffio.client import MODEL_ENDPOINTS
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
def test_create_project_payload_and_headers(tmp_path: Path):
|
|
@@ -308,7 +309,143 @@ def test_create_generation_routes_to_diffio_3_5_endpoint():
|
|
|
308
309
|
|
|
309
310
|
assert received["path"] == "/v1/diffio-3.5-generation"
|
|
310
311
|
assert received["payload"]["apiProjectId"] == "proj_35"
|
|
312
|
+
assert "idempotencyKey" not in received["payload"]
|
|
311
313
|
assert response.modelKey == "diffio-3.5"
|
|
314
|
+
assert response.idempotentReplay is None
|
|
315
|
+
|
|
316
|
+
|
|
317
|
+
def test_create_generation_sends_idempotency_key_and_parses_replay():
|
|
318
|
+
received = {}
|
|
319
|
+
|
|
320
|
+
def handler(request):
|
|
321
|
+
received["path"] = request.url.path
|
|
322
|
+
received["payload"] = json.loads(request.content.decode("utf-8"))
|
|
323
|
+
return httpx.Response(
|
|
324
|
+
200,
|
|
325
|
+
json={
|
|
326
|
+
"generationId": "gen_original",
|
|
327
|
+
"apiProjectId": "proj_123",
|
|
328
|
+
"modelKey": "diffio-2",
|
|
329
|
+
"status": "queued",
|
|
330
|
+
"idempotentReplay": True,
|
|
331
|
+
},
|
|
332
|
+
)
|
|
333
|
+
|
|
334
|
+
transport = httpx.MockTransport(handler)
|
|
335
|
+
http_client = httpx.Client(base_url="https://api.test", transport=transport)
|
|
336
|
+
client = DiffioClient(apiKey="diffio_live_test", baseUrl="https://api.test", httpClient=http_client)
|
|
337
|
+
|
|
338
|
+
response = client.create_generation(
|
|
339
|
+
apiProjectId="proj_123",
|
|
340
|
+
idempotencyKey="restore-job-2026-001",
|
|
341
|
+
)
|
|
342
|
+
|
|
343
|
+
assert received["path"] == "/v1/diffio-2.0-generation"
|
|
344
|
+
assert received["payload"] == {
|
|
345
|
+
"apiProjectId": "proj_123",
|
|
346
|
+
"idempotencyKey": "restore-job-2026-001",
|
|
347
|
+
}
|
|
348
|
+
assert response.generationId == "gen_original"
|
|
349
|
+
assert response.idempotentReplay is True
|
|
350
|
+
|
|
351
|
+
|
|
352
|
+
def test_generations_create_forwards_idempotency_key():
|
|
353
|
+
received = {}
|
|
354
|
+
|
|
355
|
+
def handler(request):
|
|
356
|
+
received["payload"] = json.loads(request.content.decode("utf-8"))
|
|
357
|
+
return httpx.Response(
|
|
358
|
+
200,
|
|
359
|
+
json={
|
|
360
|
+
"generationId": "gen_123",
|
|
361
|
+
"apiProjectId": "proj_123",
|
|
362
|
+
"modelKey": "diffio-2",
|
|
363
|
+
"status": "queued",
|
|
364
|
+
},
|
|
365
|
+
)
|
|
366
|
+
|
|
367
|
+
transport = httpx.MockTransport(handler)
|
|
368
|
+
http_client = httpx.Client(base_url="https://api.test", transport=transport)
|
|
369
|
+
client = DiffioClient(apiKey="diffio_live_test", baseUrl="https://api.test", httpClient=http_client)
|
|
370
|
+
|
|
371
|
+
response = client.generations.create(
|
|
372
|
+
apiProjectId="proj_123",
|
|
373
|
+
idempotencyKey="restore-job-2026-wrapper",
|
|
374
|
+
)
|
|
375
|
+
|
|
376
|
+
assert received["payload"]["idempotencyKey"] == "restore-job-2026-wrapper"
|
|
377
|
+
assert response.idempotentReplay is None
|
|
378
|
+
|
|
379
|
+
|
|
380
|
+
def test_generations_create_and_wait_forwards_idempotency_key():
|
|
381
|
+
received = {}
|
|
382
|
+
|
|
383
|
+
def handler(request):
|
|
384
|
+
if request.url.path == "/v1/diffio-2.0-generation":
|
|
385
|
+
received["createPayload"] = json.loads(request.content.decode("utf-8"))
|
|
386
|
+
return httpx.Response(
|
|
387
|
+
200,
|
|
388
|
+
json={
|
|
389
|
+
"generationId": "gen_123",
|
|
390
|
+
"apiProjectId": "proj_123",
|
|
391
|
+
"modelKey": "diffio-2",
|
|
392
|
+
"status": "queued",
|
|
393
|
+
"idempotentReplay": False,
|
|
394
|
+
},
|
|
395
|
+
)
|
|
396
|
+
if request.url.path == "/v1/get_generation_progress":
|
|
397
|
+
return httpx.Response(
|
|
398
|
+
200,
|
|
399
|
+
json={
|
|
400
|
+
"generationId": "gen_123",
|
|
401
|
+
"apiProjectId": "proj_123",
|
|
402
|
+
"status": "complete",
|
|
403
|
+
"hasVideo": False,
|
|
404
|
+
"preProcessing": {
|
|
405
|
+
"jobId": "job-pre",
|
|
406
|
+
"jobState": "SUCCEEDED",
|
|
407
|
+
"status": "complete",
|
|
408
|
+
"progress": 100,
|
|
409
|
+
"statusMessage": None,
|
|
410
|
+
"error": None,
|
|
411
|
+
"errorDetails": None,
|
|
412
|
+
},
|
|
413
|
+
"inference": {
|
|
414
|
+
"jobId": "job-run",
|
|
415
|
+
"jobState": "SUCCEEDED",
|
|
416
|
+
"status": "complete",
|
|
417
|
+
"progress": 100,
|
|
418
|
+
"statusMessage": None,
|
|
419
|
+
"error": None,
|
|
420
|
+
"errorDetails": None,
|
|
421
|
+
},
|
|
422
|
+
},
|
|
423
|
+
)
|
|
424
|
+
return httpx.Response(404, json={"error": "not found"})
|
|
425
|
+
|
|
426
|
+
transport = httpx.MockTransport(handler)
|
|
427
|
+
http_client = httpx.Client(base_url="https://api.test", transport=transport)
|
|
428
|
+
client = DiffioClient(apiKey="diffio_live_test", baseUrl="https://api.test", httpClient=http_client)
|
|
429
|
+
|
|
430
|
+
generation, progress = client.generations.create_and_wait(
|
|
431
|
+
apiProjectId="proj_123",
|
|
432
|
+
idempotencyKey="restore-job-2026-002",
|
|
433
|
+
pollInterval=0,
|
|
434
|
+
)
|
|
435
|
+
|
|
436
|
+
assert received["createPayload"] == {
|
|
437
|
+
"apiProjectId": "proj_123",
|
|
438
|
+
"idempotencyKey": "restore-job-2026-002",
|
|
439
|
+
}
|
|
440
|
+
assert generation.idempotentReplay is False
|
|
441
|
+
assert progress.status == "complete"
|
|
442
|
+
|
|
443
|
+
|
|
444
|
+
def test_advertised_models_match_runtime_model_support():
|
|
445
|
+
assert set(ModelKey) == set(MODEL_ENDPOINTS)
|
|
446
|
+
assert "diffio-3" not in ModelKey
|
|
447
|
+
assert "diffio-3.0-generation" not in MODEL_ENDPOINTS.values()
|
|
448
|
+
assert MODEL_ENDPOINTS["diffio-3.4"] == "diffio-3.4-generation"
|
|
312
449
|
|
|
313
450
|
|
|
314
451
|
def test_restore_audio_runs_full_flow_and_downloads(tmp_path: Path, monkeypatch):
|
|
@@ -439,6 +576,18 @@ def test_create_generation_rejects_unknown_model():
|
|
|
439
576
|
client.create_generation(apiProjectId="proj", model="diffio-unknown")
|
|
440
577
|
|
|
441
578
|
|
|
579
|
+
def test_create_generation_rejects_diffio_3():
|
|
580
|
+
def handler(request):
|
|
581
|
+
raise AssertionError("Unsupported models must be rejected before an HTTP request")
|
|
582
|
+
|
|
583
|
+
transport = httpx.MockTransport(handler)
|
|
584
|
+
http_client = httpx.Client(base_url="https://api.test", transport=transport)
|
|
585
|
+
client = DiffioClient(apiKey="diffio_live_test", baseUrl="https://api.test", httpClient=http_client)
|
|
586
|
+
|
|
587
|
+
with pytest.raises(ValueError, match="Unsupported model: diffio-3"):
|
|
588
|
+
client.create_generation(apiProjectId="proj", model="diffio-3")
|
|
589
|
+
|
|
590
|
+
|
|
442
591
|
def test_get_generation_progress_payload_and_response():
|
|
443
592
|
received = {}
|
|
444
593
|
|
|
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
|