diffio 0.1.114__tar.gz → 0.2.1__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.114/src/diffio.egg-info → diffio-0.2.1}/PKG-INFO +53 -13
- {diffio-0.1.114 → diffio-0.2.1}/README.md +52 -12
- {diffio-0.1.114 → diffio-0.2.1}/pyproject.toml +1 -1
- {diffio-0.1.114 → diffio-0.2.1}/src/diffio/__init__.py +5 -1
- {diffio-0.1.114 → diffio-0.2.1}/src/diffio/client.py +213 -77
- {diffio-0.1.114 → diffio-0.2.1}/src/diffio/types.py +80 -18
- {diffio-0.1.114 → diffio-0.2.1/src/diffio.egg-info}/PKG-INFO +53 -13
- {diffio-0.1.114 → diffio-0.2.1}/src/diffio.egg-info/SOURCES.txt +1 -1
- {diffio-0.1.114 → diffio-0.2.1}/tests/test_client.py +228 -173
- diffio-0.2.1/tests/test_diffio_api_contract.py +204 -0
- {diffio-0.1.114 → diffio-0.2.1}/tests/test_emulator_e2e.py +32 -43
- diffio-0.1.114/tests/test_diffio40_models.py +0 -48
- {diffio-0.1.114 → diffio-0.2.1}/LICENSE +0 -0
- {diffio-0.1.114 → diffio-0.2.1}/setup.cfg +0 -0
- {diffio-0.1.114 → diffio-0.2.1}/src/diffio/errors.py +0 -0
- {diffio-0.1.114 → diffio-0.2.1}/src/diffio/testing.py +0 -0
- {diffio-0.1.114 → diffio-0.2.1}/src/diffio.egg-info/dependency_links.txt +0 -0
- {diffio-0.1.114 → diffio-0.2.1}/src/diffio.egg-info/requires.txt +0 -0
- {diffio-0.1.114 → diffio-0.2.1}/src/diffio.egg-info/top_level.txt +0 -0
- {diffio-0.1.114 → diffio-0.2.1}/tests/test_transcription.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: diffio
|
|
3
|
-
Version: 0.1
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Summary: Python SDK for the Diffio API.
|
|
5
5
|
Author: Diffio
|
|
6
6
|
License: MIT
|
|
@@ -80,9 +80,30 @@ projects = client.list_projects(
|
|
|
80
80
|
)
|
|
81
81
|
```
|
|
82
82
|
|
|
83
|
+
## Models
|
|
84
|
+
|
|
85
|
+
Diffio 4.5 Flash (`diffio-4.5-flash`) and Diffio 4.5 Pro (`diffio-4.5-pro`) are the only
|
|
86
|
+
models. `diffio-4.5-flash` is the default and works on every plan; `diffio-4.5-pro` needs a
|
|
87
|
+
paid plan. Any other model id raises `ValueError` before a request is sent (the API answers
|
|
88
|
+
retired model endpoints with HTTP 410 and code `model_retired`). Existing generations created
|
|
89
|
+
with older models keep their `modelKey` and can still be listed, polled, and downloaded.
|
|
90
|
+
|
|
83
91
|
## Create a project and generation
|
|
84
92
|
|
|
85
|
-
`create_project` uploads the file and
|
|
93
|
+
`create_project` creates the project, uploads the file, and confirms the upload:
|
|
94
|
+
|
|
95
|
+
1. `POST /v1/create_project` returns the project id and an upload session (`project.upload`):
|
|
96
|
+
`edgeBaseUrl`, `uploadToken`, `objectKey`, `partSizeBytes` (32 MiB), `maxBytes`, `expiresAt`.
|
|
97
|
+
2. The file goes to the Diffio upload API at `edgeBaseUrl` in `partSizeBytes` parts
|
|
98
|
+
(`/v1/uploads/start`, `/v1/uploads/parts/{n}`, `/v1/uploads/complete`), authorized with
|
|
99
|
+
`Authorization: Bearer {uploadToken}`. Your API key is never sent to the upload API.
|
|
100
|
+
With `maxRetries` set, a failed part is retried on its own instead of resending the file.
|
|
101
|
+
If a part still fails, the SDK aborts the partial upload and raises `DiffioApiError`.
|
|
102
|
+
3. `POST /v1/complete_project_upload` confirms the upload so preprocessing starts. Its answer is
|
|
103
|
+
on `project.uploadCompletion` (`status`, `sizeBytes`). It is idempotent; you can call
|
|
104
|
+
`client.complete_project_upload(apiProjectId=...)` (or `client.projects.complete_upload`) again.
|
|
105
|
+
|
|
106
|
+
Files larger than the session's `maxBytes` (2 GiB) raise `ValueError` before any bytes are sent.
|
|
86
107
|
|
|
87
108
|
```py
|
|
88
109
|
from diffio import DiffioClient
|
|
@@ -95,8 +116,7 @@ project = client.create_project(
|
|
|
95
116
|
|
|
96
117
|
generation = client.create_generation(
|
|
97
118
|
apiProjectId=project.apiProjectId,
|
|
98
|
-
model="diffio-4.
|
|
99
|
-
sampling={"steps": 12, "guidance": 1.5},
|
|
119
|
+
model="diffio-4.5-flash",
|
|
100
120
|
idempotencyKey="restore-job-2026-001",
|
|
101
121
|
requestOptions={"maxRetries": 2},
|
|
102
122
|
)
|
|
@@ -117,8 +137,7 @@ from diffio import DiffioClient
|
|
|
117
137
|
client = DiffioClient(apiKey="diffio_live_...")
|
|
118
138
|
result = client.audio_isolation.isolate(
|
|
119
139
|
filePath="sample.wav",
|
|
120
|
-
model="diffio-4.
|
|
121
|
-
sampling={"steps": 12, "guidance": 1.5},
|
|
140
|
+
model="diffio-4.5-flash",
|
|
122
141
|
)
|
|
123
142
|
|
|
124
143
|
print(result.generation.generationId)
|
|
@@ -134,8 +153,7 @@ from diffio import DiffioClient
|
|
|
134
153
|
client = DiffioClient(apiKey="diffio_live_...")
|
|
135
154
|
audio_bytes, info = client.restore_audio(
|
|
136
155
|
filePath="sample.wav",
|
|
137
|
-
model="diffio-4.
|
|
138
|
-
sampling={"steps": 12, "guidance": 1.5},
|
|
156
|
+
model="diffio-4.5-flash",
|
|
139
157
|
onProgress=lambda progress: print(progress.status),
|
|
140
158
|
)
|
|
141
159
|
|
|
@@ -155,10 +173,13 @@ print(info["apiProjectId"], info["generationId"])
|
|
|
155
173
|
restoration or final settlement is still pending; stage progress alone does not
|
|
156
174
|
indicate overall completion.
|
|
157
175
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
176
|
+
`complete` means restored media is ready. Diffio 4.5 transcribes the recording
|
|
177
|
+
before restoration starts, so a completed generation has its transcript; while a
|
|
178
|
+
generation runs, transcription can be `pending`, `available`, or `unavailable`.
|
|
179
|
+
Read `progress.transcription.status` independently; `progress.transcription` is `None`
|
|
180
|
+
for older responses that do not report availability. `progress.stage`,
|
|
181
|
+
`progress.stageProgress`, and `progress.queue` (fleet queue position and message)
|
|
182
|
+
are set while the API reports them and `None` otherwise. A completed generation
|
|
162
183
|
remains successful if transcription is unavailable. Completion webhooks expose
|
|
163
184
|
the same optional `event.transcription` object; a later transcript does not emit
|
|
164
185
|
another `generation.completed` event.
|
|
@@ -193,7 +214,9 @@ download = client.generations.download(
|
|
|
193
214
|
print(download.downloadUrl)
|
|
194
215
|
```
|
|
195
216
|
|
|
196
|
-
If you only need the URL, use `client.generations.get_download`.
|
|
217
|
+
If you only need the URL, use `client.generations.get_download`. Download URLs point at the
|
|
218
|
+
Diffio media host, need no extra headers, and are valid for 6 hours. The response has
|
|
219
|
+
`downloadType`, `downloadUrl`, `fileName`, `storagePath`, and `mimeType`.
|
|
197
220
|
|
|
198
221
|
Set `downloadType="transcript"` to download the transcript JSON artifact when the generation has one.
|
|
199
222
|
Pending transcripts return `DiffioApiError` with `statusCode == 409` and
|
|
@@ -317,6 +340,23 @@ async def diffio_webhook(request: Request):
|
|
|
317
340
|
return {"ok": True}
|
|
318
341
|
```
|
|
319
342
|
|
|
343
|
+
## Upgrading to 0.2.0
|
|
344
|
+
|
|
345
|
+
0.2.0 follows the Diffio 4.5 API. It has breaking changes:
|
|
346
|
+
|
|
347
|
+
* Only `diffio-4.5-flash` and `diffio-4.5-pro` are accepted, and the default model is
|
|
348
|
+
`diffio-4.5-flash`. `diffio-2`, `diffio-2-flash`, `diffio-3.4`, `diffio-3.5`,
|
|
349
|
+
`diffio-4.0-flash`, and `diffio-4.0-pro` were removed with no aliases.
|
|
350
|
+
* `CreateProjectResponse` no longer has `uploadUrl`, `uploadMethod`, or `bucket`. It has
|
|
351
|
+
`upload` (a `ProjectUploadSession`) and `uploadCompletion` (a `CompleteProjectUploadResponse`).
|
|
352
|
+
Uploads use the multipart upload API instead of a single signed PUT.
|
|
353
|
+
* `GenerationDownloadResponse` no longer has `bucket`.
|
|
354
|
+
* Error messages from the upload API (`{"error": {"code", "message"}}`) become the
|
|
355
|
+
`DiffioApiError` message; the full body stays in `responseBody`.
|
|
356
|
+
|
|
357
|
+
Earlier SDK releases cannot upload to the current API: `create_project` fails with
|
|
358
|
+
`KeyError: 'uploadUrl'`.
|
|
359
|
+
|
|
320
360
|
## Tutorials
|
|
321
361
|
|
|
322
362
|
* Audio restoration CLI tutorial: `tutorials/audio-restoration-cli/README.md`
|
|
@@ -52,9 +52,30 @@ projects = client.list_projects(
|
|
|
52
52
|
)
|
|
53
53
|
```
|
|
54
54
|
|
|
55
|
+
## Models
|
|
56
|
+
|
|
57
|
+
Diffio 4.5 Flash (`diffio-4.5-flash`) and Diffio 4.5 Pro (`diffio-4.5-pro`) are the only
|
|
58
|
+
models. `diffio-4.5-flash` is the default and works on every plan; `diffio-4.5-pro` needs a
|
|
59
|
+
paid plan. Any other model id raises `ValueError` before a request is sent (the API answers
|
|
60
|
+
retired model endpoints with HTTP 410 and code `model_retired`). Existing generations created
|
|
61
|
+
with older models keep their `modelKey` and can still be listed, polled, and downloaded.
|
|
62
|
+
|
|
55
63
|
## Create a project and generation
|
|
56
64
|
|
|
57
|
-
`create_project` uploads the file and
|
|
65
|
+
`create_project` creates the project, uploads the file, and confirms the upload:
|
|
66
|
+
|
|
67
|
+
1. `POST /v1/create_project` returns the project id and an upload session (`project.upload`):
|
|
68
|
+
`edgeBaseUrl`, `uploadToken`, `objectKey`, `partSizeBytes` (32 MiB), `maxBytes`, `expiresAt`.
|
|
69
|
+
2. The file goes to the Diffio upload API at `edgeBaseUrl` in `partSizeBytes` parts
|
|
70
|
+
(`/v1/uploads/start`, `/v1/uploads/parts/{n}`, `/v1/uploads/complete`), authorized with
|
|
71
|
+
`Authorization: Bearer {uploadToken}`. Your API key is never sent to the upload API.
|
|
72
|
+
With `maxRetries` set, a failed part is retried on its own instead of resending the file.
|
|
73
|
+
If a part still fails, the SDK aborts the partial upload and raises `DiffioApiError`.
|
|
74
|
+
3. `POST /v1/complete_project_upload` confirms the upload so preprocessing starts. Its answer is
|
|
75
|
+
on `project.uploadCompletion` (`status`, `sizeBytes`). It is idempotent; you can call
|
|
76
|
+
`client.complete_project_upload(apiProjectId=...)` (or `client.projects.complete_upload`) again.
|
|
77
|
+
|
|
78
|
+
Files larger than the session's `maxBytes` (2 GiB) raise `ValueError` before any bytes are sent.
|
|
58
79
|
|
|
59
80
|
```py
|
|
60
81
|
from diffio import DiffioClient
|
|
@@ -67,8 +88,7 @@ project = client.create_project(
|
|
|
67
88
|
|
|
68
89
|
generation = client.create_generation(
|
|
69
90
|
apiProjectId=project.apiProjectId,
|
|
70
|
-
model="diffio-4.
|
|
71
|
-
sampling={"steps": 12, "guidance": 1.5},
|
|
91
|
+
model="diffio-4.5-flash",
|
|
72
92
|
idempotencyKey="restore-job-2026-001",
|
|
73
93
|
requestOptions={"maxRetries": 2},
|
|
74
94
|
)
|
|
@@ -89,8 +109,7 @@ from diffio import DiffioClient
|
|
|
89
109
|
client = DiffioClient(apiKey="diffio_live_...")
|
|
90
110
|
result = client.audio_isolation.isolate(
|
|
91
111
|
filePath="sample.wav",
|
|
92
|
-
model="diffio-4.
|
|
93
|
-
sampling={"steps": 12, "guidance": 1.5},
|
|
112
|
+
model="diffio-4.5-flash",
|
|
94
113
|
)
|
|
95
114
|
|
|
96
115
|
print(result.generation.generationId)
|
|
@@ -106,8 +125,7 @@ from diffio import DiffioClient
|
|
|
106
125
|
client = DiffioClient(apiKey="diffio_live_...")
|
|
107
126
|
audio_bytes, info = client.restore_audio(
|
|
108
127
|
filePath="sample.wav",
|
|
109
|
-
model="diffio-4.
|
|
110
|
-
sampling={"steps": 12, "guidance": 1.5},
|
|
128
|
+
model="diffio-4.5-flash",
|
|
111
129
|
onProgress=lambda progress: print(progress.status),
|
|
112
130
|
)
|
|
113
131
|
|
|
@@ -127,10 +145,13 @@ print(info["apiProjectId"], info["generationId"])
|
|
|
127
145
|
restoration or final settlement is still pending; stage progress alone does not
|
|
128
146
|
indicate overall completion.
|
|
129
147
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
148
|
+
`complete` means restored media is ready. Diffio 4.5 transcribes the recording
|
|
149
|
+
before restoration starts, so a completed generation has its transcript; while a
|
|
150
|
+
generation runs, transcription can be `pending`, `available`, or `unavailable`.
|
|
151
|
+
Read `progress.transcription.status` independently; `progress.transcription` is `None`
|
|
152
|
+
for older responses that do not report availability. `progress.stage`,
|
|
153
|
+
`progress.stageProgress`, and `progress.queue` (fleet queue position and message)
|
|
154
|
+
are set while the API reports them and `None` otherwise. A completed generation
|
|
134
155
|
remains successful if transcription is unavailable. Completion webhooks expose
|
|
135
156
|
the same optional `event.transcription` object; a later transcript does not emit
|
|
136
157
|
another `generation.completed` event.
|
|
@@ -165,7 +186,9 @@ download = client.generations.download(
|
|
|
165
186
|
print(download.downloadUrl)
|
|
166
187
|
```
|
|
167
188
|
|
|
168
|
-
If you only need the URL, use `client.generations.get_download`.
|
|
189
|
+
If you only need the URL, use `client.generations.get_download`. Download URLs point at the
|
|
190
|
+
Diffio media host, need no extra headers, and are valid for 6 hours. The response has
|
|
191
|
+
`downloadType`, `downloadUrl`, `fileName`, `storagePath`, and `mimeType`.
|
|
169
192
|
|
|
170
193
|
Set `downloadType="transcript"` to download the transcript JSON artifact when the generation has one.
|
|
171
194
|
Pending transcripts return `DiffioApiError` with `statusCode == 409` and
|
|
@@ -289,6 +312,23 @@ async def diffio_webhook(request: Request):
|
|
|
289
312
|
return {"ok": True}
|
|
290
313
|
```
|
|
291
314
|
|
|
315
|
+
## Upgrading to 0.2.0
|
|
316
|
+
|
|
317
|
+
0.2.0 follows the Diffio 4.5 API. It has breaking changes:
|
|
318
|
+
|
|
319
|
+
* Only `diffio-4.5-flash` and `diffio-4.5-pro` are accepted, and the default model is
|
|
320
|
+
`diffio-4.5-flash`. `diffio-2`, `diffio-2-flash`, `diffio-3.4`, `diffio-3.5`,
|
|
321
|
+
`diffio-4.0-flash`, and `diffio-4.0-pro` were removed with no aliases.
|
|
322
|
+
* `CreateProjectResponse` no longer has `uploadUrl`, `uploadMethod`, or `bucket`. It has
|
|
323
|
+
`upload` (a `ProjectUploadSession`) and `uploadCompletion` (a `CompleteProjectUploadResponse`).
|
|
324
|
+
Uploads use the multipart upload API instead of a single signed PUT.
|
|
325
|
+
* `GenerationDownloadResponse` no longer has `bucket`.
|
|
326
|
+
* Error messages from the upload API (`{"error": {"code", "message"}}`) become the
|
|
327
|
+
`DiffioApiError` message; the full body stays in `responseBody`.
|
|
328
|
+
|
|
329
|
+
Earlier SDK releases cannot upload to the current API: `create_project` fails with
|
|
330
|
+
`KeyError: 'uploadUrl'`.
|
|
331
|
+
|
|
292
332
|
## Tutorials
|
|
293
333
|
|
|
294
334
|
* Audio restoration CLI tutorial: `tutorials/audio-restoration-cli/README.md`
|
|
@@ -15,6 +15,7 @@ from .types import (
|
|
|
15
15
|
ApiKeyResponse,
|
|
16
16
|
ApiKeysListResponse,
|
|
17
17
|
AudioIsolationResult,
|
|
18
|
+
CompleteProjectUploadResponse,
|
|
18
19
|
CreateGenerationResponse,
|
|
19
20
|
CreateProjectResponse,
|
|
20
21
|
DownloadType,
|
|
@@ -29,6 +30,7 @@ from .types import (
|
|
|
29
30
|
ModelKey,
|
|
30
31
|
ProjectGenerationSummary,
|
|
31
32
|
ProjectSummary,
|
|
33
|
+
ProjectUploadSession,
|
|
32
34
|
TranscriptionStatus,
|
|
33
35
|
UsageSummaryResponse,
|
|
34
36
|
WebhookConfigureResponse,
|
|
@@ -45,6 +47,7 @@ __all__ = [
|
|
|
45
47
|
"ApiKeysListResponse",
|
|
46
48
|
"AudioIsolationClient",
|
|
47
49
|
"AudioIsolationResult",
|
|
50
|
+
"CompleteProjectUploadResponse",
|
|
48
51
|
"CreateGenerationResponse",
|
|
49
52
|
"CreateProjectResponse",
|
|
50
53
|
"DownloadType",
|
|
@@ -62,6 +65,7 @@ __all__ = [
|
|
|
62
65
|
"ModelKey",
|
|
63
66
|
"ProjectGenerationSummary",
|
|
64
67
|
"ProjectSummary",
|
|
68
|
+
"ProjectUploadSession",
|
|
65
69
|
"ProjectsClient",
|
|
66
70
|
"RequestOptions",
|
|
67
71
|
"TranscriptionStatus",
|
|
@@ -74,4 +78,4 @@ __all__ = [
|
|
|
74
78
|
"WebhooksClient",
|
|
75
79
|
]
|
|
76
80
|
|
|
77
|
-
__version__ = "0.1
|
|
81
|
+
__version__ = "0.2.1"
|