datalab-python-sdk 0.3.0__py3-none-any.whl → 0.4.0__py3-none-any.whl
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.
- {datalab_python_sdk-0.3.0.dist-info → datalab_python_sdk-0.4.0.dist-info}/METADATA +2 -1
- datalab_python_sdk-0.4.0.dist-info/RECORD +12 -0
- datalab_sdk/__init__.py +2 -0
- datalab_sdk/client.py +310 -24
- datalab_sdk/models.py +11 -0
- datalab_sdk/settings.py +1 -1
- datalab_python_sdk-0.3.0.dist-info/RECORD +0 -12
- {datalab_python_sdk-0.3.0.dist-info → datalab_python_sdk-0.4.0.dist-info}/WHEEL +0 -0
- {datalab_python_sdk-0.3.0.dist-info → datalab_python_sdk-0.4.0.dist-info}/entry_points.txt +0 -0
- {datalab_python_sdk-0.3.0.dist-info → datalab_python_sdk-0.4.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: datalab-python-sdk
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Summary: SDK for the Datalab document intelligence API
|
|
5
5
|
Author-email: Datalab Team <hi@datalab.to>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -9,6 +9,7 @@ Keywords: api,datalab,document-intelligence,sdk
|
|
|
9
9
|
Requires-Python: >=3.10
|
|
10
10
|
Requires-Dist: aiohttp>=3.12.14
|
|
11
11
|
Requires-Dist: click>=8.2.1
|
|
12
|
+
Requires-Dist: ijson>=3.3.0
|
|
12
13
|
Requires-Dist: pydantic-settings>=2.10.1
|
|
13
14
|
Requires-Dist: pydantic>=2.11.7
|
|
14
15
|
Requires-Dist: tenacity>=8.2.3
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
datalab_sdk/__init__.py,sha256=kK3JxJILvUTpYe6pFLMRHI19lmQL6pSY9p7urNy6-WM,1290
|
|
2
|
+
datalab_sdk/cli.py,sha256=NELgNZstpBrhPoQHqsI67kNRYew_nJpq23_ENsWvmGY,38859
|
|
3
|
+
datalab_sdk/client.py,sha256=qZyfFsalkeR715tGmMGTILtRtFsD0ILjjbQ8JoCN7LE,73975
|
|
4
|
+
datalab_sdk/exceptions.py,sha256=MDfNd-l152OUVhZSfEsE95McJq-IuOsrEsEQ4CRMbEI,785
|
|
5
|
+
datalab_sdk/mimetypes.py,sha256=a4ULJmHxoR_RMsD0j51hx0t2Q7In_PzNm7UlWX07eEE,932
|
|
6
|
+
datalab_sdk/models.py,sha256=-pxDfTG-8jmp8DG-o1waJsaIk6li6iO3MR7yDwFGZ_8,17108
|
|
7
|
+
datalab_sdk/settings.py,sha256=BoojrRcKE7T04s-vqCPFzKqopV_qqTrAtCCsjHKk3FU,365
|
|
8
|
+
datalab_python_sdk-0.4.0.dist-info/METADATA,sha256=jFyvrY1HwLRDl2_nRpUH9aV3k7FoUvtU9Dbacgp-l9w,2238
|
|
9
|
+
datalab_python_sdk-0.4.0.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
|
|
10
|
+
datalab_python_sdk-0.4.0.dist-info/entry_points.txt,sha256=rqWxO21UV57JxxyeF20iBTxHpzBYOA69hCHIqwdn-Ok,48
|
|
11
|
+
datalab_python_sdk-0.4.0.dist-info/licenses/LICENSE,sha256=XGjT-Uz6t7UZzr3JCZfilsGcZEgMm_1aONcRunohxWg,1064
|
|
12
|
+
datalab_python_sdk-0.4.0.dist-info/RECORD,,
|
datalab_sdk/__init__.py
CHANGED
|
@@ -10,6 +10,7 @@ from .exceptions import DatalabError, DatalabAPIError, DatalabTimeoutError
|
|
|
10
10
|
from .models import (
|
|
11
11
|
ConversionResult,
|
|
12
12
|
CreateDocumentResult,
|
|
13
|
+
FileResult,
|
|
13
14
|
OCRResult,
|
|
14
15
|
ConvertOptions,
|
|
15
16
|
ExtractOptions,
|
|
@@ -36,6 +37,7 @@ __all__ = [
|
|
|
36
37
|
"DatalabTimeoutError",
|
|
37
38
|
"ConversionResult",
|
|
38
39
|
"CreateDocumentResult",
|
|
40
|
+
"FileResult",
|
|
39
41
|
"OCRResult",
|
|
40
42
|
"ConvertOptions",
|
|
41
43
|
"ExtractOptions",
|
datalab_sdk/client.py
CHANGED
|
@@ -4,8 +4,13 @@ Datalab API client - async core with sync wrapper
|
|
|
4
4
|
|
|
5
5
|
import asyncio
|
|
6
6
|
import mimetypes
|
|
7
|
+
import os
|
|
8
|
+
import shutil
|
|
9
|
+
import tempfile
|
|
7
10
|
import warnings
|
|
11
|
+
|
|
8
12
|
import aiohttp
|
|
13
|
+
import ijson
|
|
9
14
|
from tenacity import (
|
|
10
15
|
retry,
|
|
11
16
|
retry_if_exception,
|
|
@@ -25,6 +30,7 @@ from datalab_sdk.mimetypes import MIMETYPE_MAP
|
|
|
25
30
|
from datalab_sdk.models import (
|
|
26
31
|
ConversionResult,
|
|
27
32
|
CreateDocumentResult,
|
|
33
|
+
FileResult,
|
|
28
34
|
OCRResult,
|
|
29
35
|
ProcessingOptions,
|
|
30
36
|
ConvertOptions,
|
|
@@ -44,6 +50,21 @@ from datalab_sdk.models import (
|
|
|
44
50
|
from datalab_sdk.settings import settings
|
|
45
51
|
|
|
46
52
|
|
|
53
|
+
class _AsyncIterableReader:
|
|
54
|
+
"""Adapts an async iterable of bytes into an async file-like object for ijson."""
|
|
55
|
+
|
|
56
|
+
def __init__(self, async_iterable):
|
|
57
|
+
self._iter = async_iterable.__aiter__()
|
|
58
|
+
|
|
59
|
+
async def read(self, n=-1):
|
|
60
|
+
if n == 0:
|
|
61
|
+
return b""
|
|
62
|
+
try:
|
|
63
|
+
return await self._iter.__anext__()
|
|
64
|
+
except StopAsyncIteration:
|
|
65
|
+
return b""
|
|
66
|
+
|
|
67
|
+
|
|
47
68
|
class AsyncDatalabClient:
|
|
48
69
|
"""Asynchronous client for Datalab API"""
|
|
49
70
|
|
|
@@ -150,8 +171,12 @@ class AsyncDatalabClient:
|
|
|
150
171
|
return await self._make_request("POST", endpoint, **kwargs)
|
|
151
172
|
|
|
152
173
|
async def _poll_result(
|
|
153
|
-
self,
|
|
154
|
-
|
|
174
|
+
self,
|
|
175
|
+
check_url: str,
|
|
176
|
+
max_polls: int = 300,
|
|
177
|
+
poll_interval: int = 1,
|
|
178
|
+
stream_response_to: Optional[Path] = None,
|
|
179
|
+
) -> Union[Dict[str, Any], FileResult]:
|
|
155
180
|
"""Poll for result completion"""
|
|
156
181
|
full_url = (
|
|
157
182
|
check_url
|
|
@@ -160,14 +185,21 @@ class AsyncDatalabClient:
|
|
|
160
185
|
)
|
|
161
186
|
|
|
162
187
|
for i in range(max_polls):
|
|
163
|
-
|
|
188
|
+
if stream_response_to:
|
|
189
|
+
result = await self._poll_get_streaming(full_url, stream_response_to)
|
|
190
|
+
status, success, error = result.status, result.success, result.error
|
|
191
|
+
else:
|
|
192
|
+
data = await self._poll_get_with_retry(full_url)
|
|
193
|
+
status = data.get("status")
|
|
194
|
+
success = data.get("success", True)
|
|
195
|
+
error = data.get("error")
|
|
164
196
|
|
|
165
|
-
if
|
|
166
|
-
return data
|
|
197
|
+
if status == "complete":
|
|
198
|
+
return result if stream_response_to else data
|
|
167
199
|
|
|
168
|
-
if not
|
|
200
|
+
if not success and status != "processing":
|
|
169
201
|
raise DatalabAPIError(
|
|
170
|
-
f"Processing failed: {
|
|
202
|
+
f"Processing failed: {error or 'Unknown error'}"
|
|
171
203
|
)
|
|
172
204
|
|
|
173
205
|
await asyncio.sleep(poll_interval)
|
|
@@ -202,6 +234,116 @@ class AsyncDatalabClient:
|
|
|
202
234
|
"""GET wrapper for polling with scoped retries for transient failures"""
|
|
203
235
|
return await self._make_request("GET", url)
|
|
204
236
|
|
|
237
|
+
@staticmethod
|
|
238
|
+
async def _tee_stream_to_file(content, fd):
|
|
239
|
+
"""Async generator that writes each chunk to fd and yields it for ijson."""
|
|
240
|
+
async for chunk in content.iter_any():
|
|
241
|
+
os.write(fd, chunk)
|
|
242
|
+
yield chunk
|
|
243
|
+
|
|
244
|
+
@retry(
|
|
245
|
+
retry=(
|
|
246
|
+
retry_if_exception_type(DatalabTimeoutError)
|
|
247
|
+
| retry_if_exception(
|
|
248
|
+
lambda e: isinstance(e, DatalabAPIError)
|
|
249
|
+
and (
|
|
250
|
+
getattr(e, "status_code", None) in (408, 429)
|
|
251
|
+
or (
|
|
252
|
+
getattr(e, "status_code", None) is not None
|
|
253
|
+
and getattr(e, "status_code") >= 500
|
|
254
|
+
)
|
|
255
|
+
or getattr(e, "status_code", None) is None
|
|
256
|
+
)
|
|
257
|
+
)
|
|
258
|
+
),
|
|
259
|
+
stop=stop_after_attempt(10),
|
|
260
|
+
wait=wait_exponential_jitter(initial=5, max=120),
|
|
261
|
+
reraise=True,
|
|
262
|
+
)
|
|
263
|
+
async def _poll_get_streaming(self, url: str, stream_response_to: Path) -> FileResult:
|
|
264
|
+
"""GET with streaming to disk. Extracts status/success/error via ijson."""
|
|
265
|
+
await self._ensure_session()
|
|
266
|
+
|
|
267
|
+
fd = None
|
|
268
|
+
tmp_path = None
|
|
269
|
+
try:
|
|
270
|
+
fd, tmp_path = tempfile.mkstemp()
|
|
271
|
+
|
|
272
|
+
try:
|
|
273
|
+
resp = await self._session.get(url)
|
|
274
|
+
except asyncio.TimeoutError:
|
|
275
|
+
raise DatalabTimeoutError(f"Request timed out after {self.timeout} seconds")
|
|
276
|
+
except aiohttp.ClientError as e:
|
|
277
|
+
raise DatalabAPIError(f"Request failed: {str(e)}")
|
|
278
|
+
|
|
279
|
+
try:
|
|
280
|
+
if resp.status >= 400:
|
|
281
|
+
body = await resp.read()
|
|
282
|
+
try:
|
|
283
|
+
import json as _json
|
|
284
|
+
error_data = _json.loads(body)
|
|
285
|
+
error_message = (
|
|
286
|
+
error_data.get("detail") or error_data.get("error") or str(resp.status)
|
|
287
|
+
)
|
|
288
|
+
except Exception:
|
|
289
|
+
error_message = f"HTTP {resp.status}"
|
|
290
|
+
raise DatalabAPIError(error_message, resp.status)
|
|
291
|
+
|
|
292
|
+
status = None
|
|
293
|
+
success = None
|
|
294
|
+
error = None
|
|
295
|
+
|
|
296
|
+
tee_reader = _AsyncIterableReader(
|
|
297
|
+
self._tee_stream_to_file(resp.content, fd)
|
|
298
|
+
)
|
|
299
|
+
async for prefix, event, value in ijson.parse_async(tee_reader):
|
|
300
|
+
if prefix == "status" and event == "string":
|
|
301
|
+
status = value
|
|
302
|
+
elif prefix == "success" and event == "boolean":
|
|
303
|
+
success = value
|
|
304
|
+
elif prefix == "error" and event in ("string", "null"):
|
|
305
|
+
error = value
|
|
306
|
+
finally:
|
|
307
|
+
resp.release()
|
|
308
|
+
|
|
309
|
+
if status is None:
|
|
310
|
+
raise DatalabAPIError("Response missing 'status' field")
|
|
311
|
+
|
|
312
|
+
if success is None:
|
|
313
|
+
success = True
|
|
314
|
+
|
|
315
|
+
# Close fd before moving
|
|
316
|
+
os.close(fd)
|
|
317
|
+
fd = None
|
|
318
|
+
|
|
319
|
+
if status == "complete":
|
|
320
|
+
shutil.move(tmp_path, stream_response_to)
|
|
321
|
+
tmp_path = None
|
|
322
|
+
return FileResult(
|
|
323
|
+
success=success,
|
|
324
|
+
status=status,
|
|
325
|
+
output_path=stream_response_to,
|
|
326
|
+
error=error,
|
|
327
|
+
)
|
|
328
|
+
else:
|
|
329
|
+
return FileResult(
|
|
330
|
+
success=success,
|
|
331
|
+
status=status,
|
|
332
|
+
output_path=stream_response_to,
|
|
333
|
+
error=error,
|
|
334
|
+
)
|
|
335
|
+
finally:
|
|
336
|
+
if fd is not None:
|
|
337
|
+
try:
|
|
338
|
+
os.close(fd)
|
|
339
|
+
except OSError:
|
|
340
|
+
pass
|
|
341
|
+
if tmp_path is not None:
|
|
342
|
+
try:
|
|
343
|
+
os.unlink(tmp_path)
|
|
344
|
+
except OSError:
|
|
345
|
+
pass
|
|
346
|
+
|
|
205
347
|
def _prepare_file_data(self, file_path: Union[str, Path]) -> tuple:
|
|
206
348
|
"""Prepare file data for upload"""
|
|
207
349
|
file_path = Path(file_path)
|
|
@@ -284,7 +426,8 @@ class AsyncDatalabClient:
|
|
|
284
426
|
data: aiohttp.FormData,
|
|
285
427
|
max_polls: int = 300,
|
|
286
428
|
poll_interval: int = 1,
|
|
287
|
-
|
|
429
|
+
stream_response_to: Optional[Path] = None,
|
|
430
|
+
) -> Union[Dict[str, Any], FileResult]:
|
|
288
431
|
"""Submit a request and poll for the result"""
|
|
289
432
|
initial_data = await self._submit_with_retry(endpoint, data=data)
|
|
290
433
|
|
|
@@ -297,6 +440,7 @@ class AsyncDatalabClient:
|
|
|
297
440
|
initial_data["request_check_url"],
|
|
298
441
|
max_polls=max_polls,
|
|
299
442
|
poll_interval=poll_interval,
|
|
443
|
+
stream_response_to=stream_response_to,
|
|
300
444
|
)
|
|
301
445
|
|
|
302
446
|
# Convenient endpoint-specific methods
|
|
@@ -306,9 +450,10 @@ class AsyncDatalabClient:
|
|
|
306
450
|
file_url: Optional[str] = None,
|
|
307
451
|
options: Optional[ConvertOptions] = None,
|
|
308
452
|
save_output: Optional[Union[str, Path]] = None,
|
|
453
|
+
stream_response_to: Optional[Union[str, Path]] = None,
|
|
309
454
|
max_polls: int = 300,
|
|
310
455
|
poll_interval: int = 1,
|
|
311
|
-
) -> ConversionResult:
|
|
456
|
+
) -> Union[ConversionResult, FileResult]:
|
|
312
457
|
"""
|
|
313
458
|
Convert a document to markdown, HTML, JSON, or chunks
|
|
314
459
|
|
|
@@ -317,9 +462,19 @@ class AsyncDatalabClient:
|
|
|
317
462
|
file_url: URL of the file to convert
|
|
318
463
|
options: Processing options for conversion
|
|
319
464
|
save_output: Optional path to save output files
|
|
465
|
+
stream_response_to: Optional path to stream raw JSON response to disk
|
|
320
466
|
max_polls: Maximum number of polling attempts
|
|
321
467
|
poll_interval: Seconds between polling attempts
|
|
322
468
|
"""
|
|
469
|
+
if save_output and stream_response_to:
|
|
470
|
+
raise ValueError("Cannot use both 'save_output' and 'stream_response_to'.")
|
|
471
|
+
|
|
472
|
+
resolved_stream_response_to = None
|
|
473
|
+
if stream_response_to:
|
|
474
|
+
resolved_stream_response_to = Path(stream_response_to)
|
|
475
|
+
if not resolved_stream_response_to.parent.is_dir():
|
|
476
|
+
raise ValueError(f"Directory does not exist: {resolved_stream_response_to.parent}")
|
|
477
|
+
|
|
323
478
|
if options is None:
|
|
324
479
|
options = ConvertOptions()
|
|
325
480
|
|
|
@@ -330,8 +485,12 @@ class AsyncDatalabClient:
|
|
|
330
485
|
),
|
|
331
486
|
max_polls=max_polls,
|
|
332
487
|
poll_interval=poll_interval,
|
|
488
|
+
stream_response_to=resolved_stream_response_to,
|
|
333
489
|
)
|
|
334
490
|
|
|
491
|
+
if isinstance(result_data, FileResult):
|
|
492
|
+
return result_data
|
|
493
|
+
|
|
335
494
|
result = self._build_conversion_result(result_data, options.output_format)
|
|
336
495
|
|
|
337
496
|
# Save output if requested
|
|
@@ -348,9 +507,10 @@ class AsyncDatalabClient:
|
|
|
348
507
|
file_url: Optional[str] = None,
|
|
349
508
|
options: Optional[ExtractOptions] = None,
|
|
350
509
|
save_output: Optional[Union[str, Path]] = None,
|
|
510
|
+
stream_response_to: Optional[Union[str, Path]] = None,
|
|
351
511
|
max_polls: int = 300,
|
|
352
512
|
poll_interval: int = 1,
|
|
353
|
-
) -> ConversionResult:
|
|
513
|
+
) -> Union[ConversionResult, FileResult]:
|
|
354
514
|
"""
|
|
355
515
|
Extract structured data from a document using a JSON schema
|
|
356
516
|
|
|
@@ -362,9 +522,19 @@ class AsyncDatalabClient:
|
|
|
362
522
|
file_url: URL of the file to extract from
|
|
363
523
|
options: Extraction options (must include page_schema)
|
|
364
524
|
save_output: Optional path to save output files
|
|
525
|
+
stream_response_to: Optional path to stream raw JSON response to disk
|
|
365
526
|
max_polls: Maximum number of polling attempts
|
|
366
527
|
poll_interval: Seconds between polling attempts
|
|
367
528
|
"""
|
|
529
|
+
if save_output and stream_response_to:
|
|
530
|
+
raise ValueError("Cannot use both 'save_output' and 'stream_response_to'.")
|
|
531
|
+
|
|
532
|
+
resolved_stream_response_to = None
|
|
533
|
+
if stream_response_to:
|
|
534
|
+
resolved_stream_response_to = Path(stream_response_to)
|
|
535
|
+
if not resolved_stream_response_to.parent.is_dir():
|
|
536
|
+
raise ValueError(f"Directory does not exist: {resolved_stream_response_to.parent}")
|
|
537
|
+
|
|
368
538
|
if options is None:
|
|
369
539
|
raise ValueError("options must be provided with page_schema")
|
|
370
540
|
|
|
@@ -383,8 +553,12 @@ class AsyncDatalabClient:
|
|
|
383
553
|
),
|
|
384
554
|
max_polls=max_polls,
|
|
385
555
|
poll_interval=poll_interval,
|
|
556
|
+
stream_response_to=resolved_stream_response_to,
|
|
386
557
|
)
|
|
387
558
|
|
|
559
|
+
if isinstance(result_data, FileResult):
|
|
560
|
+
return result_data
|
|
561
|
+
|
|
388
562
|
result = self._build_conversion_result(result_data, options.output_format)
|
|
389
563
|
|
|
390
564
|
if save_output and result.success:
|
|
@@ -400,9 +574,10 @@ class AsyncDatalabClient:
|
|
|
400
574
|
file_url: Optional[str] = None,
|
|
401
575
|
options: Optional[SegmentOptions] = None,
|
|
402
576
|
save_output: Optional[Union[str, Path]] = None,
|
|
577
|
+
stream_response_to: Optional[Union[str, Path]] = None,
|
|
403
578
|
max_polls: int = 300,
|
|
404
579
|
poll_interval: int = 1,
|
|
405
|
-
) -> ConversionResult:
|
|
580
|
+
) -> Union[ConversionResult, FileResult]:
|
|
406
581
|
"""
|
|
407
582
|
Segment a document into sections using a schema
|
|
408
583
|
|
|
@@ -414,9 +589,19 @@ class AsyncDatalabClient:
|
|
|
414
589
|
file_url: URL of the file to segment
|
|
415
590
|
options: Segmentation options (must include segmentation_schema)
|
|
416
591
|
save_output: Optional path to save output files
|
|
592
|
+
stream_response_to: Optional path to stream raw JSON response to disk
|
|
417
593
|
max_polls: Maximum number of polling attempts
|
|
418
594
|
poll_interval: Seconds between polling attempts
|
|
419
595
|
"""
|
|
596
|
+
if save_output and stream_response_to:
|
|
597
|
+
raise ValueError("Cannot use both 'save_output' and 'stream_response_to'.")
|
|
598
|
+
|
|
599
|
+
resolved_stream_response_to = None
|
|
600
|
+
if stream_response_to:
|
|
601
|
+
resolved_stream_response_to = Path(stream_response_to)
|
|
602
|
+
if not resolved_stream_response_to.parent.is_dir():
|
|
603
|
+
raise ValueError(f"Directory does not exist: {resolved_stream_response_to.parent}")
|
|
604
|
+
|
|
420
605
|
if options is None:
|
|
421
606
|
raise ValueError("options must be provided with segmentation_schema")
|
|
422
607
|
|
|
@@ -435,8 +620,12 @@ class AsyncDatalabClient:
|
|
|
435
620
|
),
|
|
436
621
|
max_polls=max_polls,
|
|
437
622
|
poll_interval=poll_interval,
|
|
623
|
+
stream_response_to=resolved_stream_response_to,
|
|
438
624
|
)
|
|
439
625
|
|
|
626
|
+
if isinstance(result_data, FileResult):
|
|
627
|
+
return result_data
|
|
628
|
+
|
|
440
629
|
result = self._build_conversion_result(result_data, "markdown")
|
|
441
630
|
|
|
442
631
|
if save_output and result.success:
|
|
@@ -452,9 +641,10 @@ class AsyncDatalabClient:
|
|
|
452
641
|
file_url: Optional[str] = None,
|
|
453
642
|
options: Optional[CustomPipelineOptions] = None,
|
|
454
643
|
save_output: Optional[Union[str, Path]] = None,
|
|
644
|
+
stream_response_to: Optional[Union[str, Path]] = None,
|
|
455
645
|
max_polls: int = 300,
|
|
456
646
|
poll_interval: int = 1,
|
|
457
|
-
) -> ConversionResult:
|
|
647
|
+
) -> Union[ConversionResult, FileResult]:
|
|
458
648
|
"""
|
|
459
649
|
Execute a custom pipeline configuration
|
|
460
650
|
|
|
@@ -463,9 +653,19 @@ class AsyncDatalabClient:
|
|
|
463
653
|
file_url: URL of the file to process
|
|
464
654
|
options: Custom pipeline options (must include pipeline_id)
|
|
465
655
|
save_output: Optional path to save output files
|
|
656
|
+
stream_response_to: Optional path to stream raw JSON response to disk
|
|
466
657
|
max_polls: Maximum number of polling attempts
|
|
467
658
|
poll_interval: Seconds between polling attempts
|
|
468
659
|
"""
|
|
660
|
+
if save_output and stream_response_to:
|
|
661
|
+
raise ValueError("Cannot use both 'save_output' and 'stream_response_to'.")
|
|
662
|
+
|
|
663
|
+
resolved_stream_response_to = None
|
|
664
|
+
if stream_response_to:
|
|
665
|
+
resolved_stream_response_to = Path(stream_response_to)
|
|
666
|
+
if not resolved_stream_response_to.parent.is_dir():
|
|
667
|
+
raise ValueError(f"Directory does not exist: {resolved_stream_response_to.parent}")
|
|
668
|
+
|
|
469
669
|
if options is None:
|
|
470
670
|
raise ValueError("options must be provided with pipeline_id")
|
|
471
671
|
|
|
@@ -476,8 +676,12 @@ class AsyncDatalabClient:
|
|
|
476
676
|
),
|
|
477
677
|
max_polls=max_polls,
|
|
478
678
|
poll_interval=poll_interval,
|
|
679
|
+
stream_response_to=resolved_stream_response_to,
|
|
479
680
|
)
|
|
480
681
|
|
|
682
|
+
if isinstance(result_data, FileResult):
|
|
683
|
+
return result_data
|
|
684
|
+
|
|
481
685
|
result = self._build_conversion_result(result_data, options.output_format)
|
|
482
686
|
|
|
483
687
|
if save_output and result.success:
|
|
@@ -493,9 +697,10 @@ class AsyncDatalabClient:
|
|
|
493
697
|
file_url: Optional[str] = None,
|
|
494
698
|
options: Optional[TrackChangesOptions] = None,
|
|
495
699
|
save_output: Optional[Union[str, Path]] = None,
|
|
700
|
+
stream_response_to: Optional[Union[str, Path]] = None,
|
|
496
701
|
max_polls: int = 300,
|
|
497
702
|
poll_interval: int = 1,
|
|
498
|
-
) -> ConversionResult:
|
|
703
|
+
) -> Union[ConversionResult, FileResult]:
|
|
499
704
|
"""
|
|
500
705
|
Extract and display tracked changes from DOCX documents
|
|
501
706
|
|
|
@@ -504,9 +709,19 @@ class AsyncDatalabClient:
|
|
|
504
709
|
file_url: URL of the DOCX file
|
|
505
710
|
options: Track changes options
|
|
506
711
|
save_output: Optional path to save output files
|
|
712
|
+
stream_response_to: Optional path to stream raw JSON response to disk
|
|
507
713
|
max_polls: Maximum number of polling attempts
|
|
508
714
|
poll_interval: Seconds between polling attempts
|
|
509
715
|
"""
|
|
716
|
+
if save_output and stream_response_to:
|
|
717
|
+
raise ValueError("Cannot use both 'save_output' and 'stream_response_to'.")
|
|
718
|
+
|
|
719
|
+
resolved_stream_response_to = None
|
|
720
|
+
if stream_response_to:
|
|
721
|
+
resolved_stream_response_to = Path(stream_response_to)
|
|
722
|
+
if not resolved_stream_response_to.parent.is_dir():
|
|
723
|
+
raise ValueError(f"Directory does not exist: {resolved_stream_response_to.parent}")
|
|
724
|
+
|
|
510
725
|
if options is None:
|
|
511
726
|
options = TrackChangesOptions()
|
|
512
727
|
|
|
@@ -517,8 +732,12 @@ class AsyncDatalabClient:
|
|
|
517
732
|
),
|
|
518
733
|
max_polls=max_polls,
|
|
519
734
|
poll_interval=poll_interval,
|
|
735
|
+
stream_response_to=resolved_stream_response_to,
|
|
520
736
|
)
|
|
521
737
|
|
|
738
|
+
if isinstance(result_data, FileResult):
|
|
739
|
+
return result_data
|
|
740
|
+
|
|
522
741
|
result = self._build_conversion_result(result_data, options.output_format)
|
|
523
742
|
|
|
524
743
|
if save_output and result.success:
|
|
@@ -534,9 +753,10 @@ class AsyncDatalabClient:
|
|
|
534
753
|
output_format: str = "docx",
|
|
535
754
|
webhook_url: Optional[str] = None,
|
|
536
755
|
save_output: Optional[Union[str, Path]] = None,
|
|
756
|
+
stream_response_to: Optional[Union[str, Path]] = None,
|
|
537
757
|
max_polls: int = 300,
|
|
538
758
|
poll_interval: int = 1,
|
|
539
|
-
) -> CreateDocumentResult:
|
|
759
|
+
) -> Union[CreateDocumentResult, FileResult]:
|
|
540
760
|
"""
|
|
541
761
|
Create a DOCX document from markdown with track changes support
|
|
542
762
|
|
|
@@ -550,9 +770,19 @@ class AsyncDatalabClient:
|
|
|
550
770
|
output_format: Output format (currently only 'docx')
|
|
551
771
|
webhook_url: Optional webhook URL for completion notification
|
|
552
772
|
save_output: Optional path to save the output file
|
|
773
|
+
stream_response_to: Optional path to stream raw JSON response to disk
|
|
553
774
|
max_polls: Maximum number of polling attempts
|
|
554
775
|
poll_interval: Seconds between polling attempts
|
|
555
776
|
"""
|
|
777
|
+
if save_output and stream_response_to:
|
|
778
|
+
raise ValueError("Cannot use both 'save_output' and 'stream_response_to'.")
|
|
779
|
+
|
|
780
|
+
resolved_stream_response_to = None
|
|
781
|
+
if stream_response_to:
|
|
782
|
+
resolved_stream_response_to = Path(stream_response_to)
|
|
783
|
+
if not resolved_stream_response_to.parent.is_dir():
|
|
784
|
+
raise ValueError(f"Directory does not exist: {resolved_stream_response_to.parent}")
|
|
785
|
+
|
|
556
786
|
payload = {
|
|
557
787
|
"markdown": markdown,
|
|
558
788
|
"output_format": output_format,
|
|
@@ -574,8 +804,12 @@ class AsyncDatalabClient:
|
|
|
574
804
|
initial_data["request_check_url"],
|
|
575
805
|
max_polls=max_polls,
|
|
576
806
|
poll_interval=poll_interval,
|
|
807
|
+
stream_response_to=resolved_stream_response_to,
|
|
577
808
|
)
|
|
578
809
|
|
|
810
|
+
if isinstance(result_data, FileResult):
|
|
811
|
+
return result_data
|
|
812
|
+
|
|
579
813
|
result = CreateDocumentResult(
|
|
580
814
|
status=result_data.get("status", "complete"),
|
|
581
815
|
success=result_data.get("success"),
|
|
@@ -600,14 +834,24 @@ class AsyncDatalabClient:
|
|
|
600
834
|
file_path: Union[str, Path],
|
|
601
835
|
options: Optional[ProcessingOptions] = None,
|
|
602
836
|
save_output: Optional[Union[str, Path]] = None,
|
|
837
|
+
stream_response_to: Optional[Union[str, Path]] = None,
|
|
603
838
|
max_polls: int = 300,
|
|
604
839
|
poll_interval: int = 1,
|
|
605
|
-
) -> OCRResult:
|
|
840
|
+
) -> Union[OCRResult, FileResult]:
|
|
606
841
|
"""Perform OCR on a document
|
|
607
842
|
|
|
608
843
|
.. deprecated::
|
|
609
844
|
The /ocr endpoint is deprecated. Use convert() instead.
|
|
610
845
|
"""
|
|
846
|
+
if save_output and stream_response_to:
|
|
847
|
+
raise ValueError("Cannot use both 'save_output' and 'stream_response_to'.")
|
|
848
|
+
|
|
849
|
+
resolved_stream_response_to = None
|
|
850
|
+
if stream_response_to:
|
|
851
|
+
resolved_stream_response_to = Path(stream_response_to)
|
|
852
|
+
if not resolved_stream_response_to.parent.is_dir():
|
|
853
|
+
raise ValueError(f"Directory does not exist: {resolved_stream_response_to.parent}")
|
|
854
|
+
|
|
611
855
|
warnings.warn(
|
|
612
856
|
"The ocr() method is deprecated and will be removed in a future version. "
|
|
613
857
|
"Use convert() instead.",
|
|
@@ -631,8 +875,12 @@ class AsyncDatalabClient:
|
|
|
631
875
|
initial_data["request_check_url"],
|
|
632
876
|
max_polls=max_polls,
|
|
633
877
|
poll_interval=poll_interval,
|
|
878
|
+
stream_response_to=resolved_stream_response_to,
|
|
634
879
|
)
|
|
635
880
|
|
|
881
|
+
if isinstance(result_data, FileResult):
|
|
882
|
+
return result_data
|
|
883
|
+
|
|
636
884
|
result = OCRResult(
|
|
637
885
|
success=result_data.get("success", False),
|
|
638
886
|
pages=result_data.get("pages", []),
|
|
@@ -657,9 +905,10 @@ class AsyncDatalabClient:
|
|
|
657
905
|
file_url: Optional[str] = None,
|
|
658
906
|
options: Optional[FormFillingOptions] = None,
|
|
659
907
|
save_output: Optional[Union[str, Path]] = None,
|
|
908
|
+
stream_response_to: Optional[Union[str, Path]] = None,
|
|
660
909
|
max_polls: int = 300,
|
|
661
910
|
poll_interval: int = 1,
|
|
662
|
-
) -> FormFillingResult:
|
|
911
|
+
) -> Union[FormFillingResult, FileResult]:
|
|
663
912
|
"""
|
|
664
913
|
Fill PDF or image forms with provided field data
|
|
665
914
|
|
|
@@ -668,9 +917,19 @@ class AsyncDatalabClient:
|
|
|
668
917
|
file_url: URL of the file to fill
|
|
669
918
|
options: Form filling options (must include field_data)
|
|
670
919
|
save_output: Optional path to save output files
|
|
920
|
+
stream_response_to: Optional path to stream raw JSON response to disk
|
|
671
921
|
max_polls: Maximum number of polling attempts
|
|
672
922
|
poll_interval: Seconds between polling attempts
|
|
673
923
|
"""
|
|
924
|
+
if save_output and stream_response_to:
|
|
925
|
+
raise ValueError("Cannot use both 'save_output' and 'stream_response_to'.")
|
|
926
|
+
|
|
927
|
+
resolved_stream_response_to = None
|
|
928
|
+
if stream_response_to:
|
|
929
|
+
resolved_stream_response_to = Path(stream_response_to)
|
|
930
|
+
if not resolved_stream_response_to.parent.is_dir():
|
|
931
|
+
raise ValueError(f"Directory does not exist: {resolved_stream_response_to.parent}")
|
|
932
|
+
|
|
674
933
|
if options is None:
|
|
675
934
|
raise ValueError("options must be provided with field_data")
|
|
676
935
|
|
|
@@ -690,8 +949,12 @@ class AsyncDatalabClient:
|
|
|
690
949
|
initial_data["request_check_url"],
|
|
691
950
|
max_polls=max_polls,
|
|
692
951
|
poll_interval=poll_interval,
|
|
952
|
+
stream_response_to=resolved_stream_response_to,
|
|
693
953
|
)
|
|
694
954
|
|
|
955
|
+
if isinstance(result_data, FileResult):
|
|
956
|
+
return result_data
|
|
957
|
+
|
|
695
958
|
result = FormFillingResult(
|
|
696
959
|
status=result_data.get("status", "complete"),
|
|
697
960
|
success=result_data.get("success"),
|
|
@@ -1344,9 +1607,10 @@ class DatalabClient:
|
|
|
1344
1607
|
file_url: Optional[str] = None,
|
|
1345
1608
|
options: Optional[ConvertOptions] = None,
|
|
1346
1609
|
save_output: Optional[Union[str, Path]] = None,
|
|
1610
|
+
stream_response_to: Optional[Union[str, Path]] = None,
|
|
1347
1611
|
max_polls: int = 300,
|
|
1348
1612
|
poll_interval: int = 1,
|
|
1349
|
-
) -> ConversionResult:
|
|
1613
|
+
) -> Union[ConversionResult, FileResult]:
|
|
1350
1614
|
"""
|
|
1351
1615
|
Convert a document to markdown, HTML, JSON, or chunks (sync version)
|
|
1352
1616
|
|
|
@@ -1355,6 +1619,7 @@ class DatalabClient:
|
|
|
1355
1619
|
file_url: URL of the file to convert
|
|
1356
1620
|
options: Processing options for conversion
|
|
1357
1621
|
save_output: Optional path to save output files
|
|
1622
|
+
stream_response_to: Optional path to stream raw JSON response to disk
|
|
1358
1623
|
max_polls: Maximum number of polling attempts
|
|
1359
1624
|
poll_interval: Seconds between polling attempts
|
|
1360
1625
|
"""
|
|
@@ -1364,6 +1629,7 @@ class DatalabClient:
|
|
|
1364
1629
|
file_url=file_url,
|
|
1365
1630
|
options=options,
|
|
1366
1631
|
save_output=save_output,
|
|
1632
|
+
stream_response_to=stream_response_to,
|
|
1367
1633
|
max_polls=max_polls,
|
|
1368
1634
|
poll_interval=poll_interval,
|
|
1369
1635
|
)
|
|
@@ -1375,9 +1641,10 @@ class DatalabClient:
|
|
|
1375
1641
|
file_url: Optional[str] = None,
|
|
1376
1642
|
options: Optional[ExtractOptions] = None,
|
|
1377
1643
|
save_output: Optional[Union[str, Path]] = None,
|
|
1644
|
+
stream_response_to: Optional[Union[str, Path]] = None,
|
|
1378
1645
|
max_polls: int = 300,
|
|
1379
1646
|
poll_interval: int = 1,
|
|
1380
|
-
) -> ConversionResult:
|
|
1647
|
+
) -> Union[ConversionResult, FileResult]:
|
|
1381
1648
|
"""
|
|
1382
1649
|
Extract structured data from a document using a JSON schema (sync version)
|
|
1383
1650
|
|
|
@@ -1386,6 +1653,7 @@ class DatalabClient:
|
|
|
1386
1653
|
file_url: URL of the file to extract from
|
|
1387
1654
|
options: Extraction options (must include page_schema)
|
|
1388
1655
|
save_output: Optional path to save output files
|
|
1656
|
+
stream_response_to: Optional path to stream raw JSON response to disk
|
|
1389
1657
|
max_polls: Maximum number of polling attempts
|
|
1390
1658
|
poll_interval: Seconds between polling attempts
|
|
1391
1659
|
"""
|
|
@@ -1395,6 +1663,7 @@ class DatalabClient:
|
|
|
1395
1663
|
file_url=file_url,
|
|
1396
1664
|
options=options,
|
|
1397
1665
|
save_output=save_output,
|
|
1666
|
+
stream_response_to=stream_response_to,
|
|
1398
1667
|
max_polls=max_polls,
|
|
1399
1668
|
poll_interval=poll_interval,
|
|
1400
1669
|
)
|
|
@@ -1406,9 +1675,10 @@ class DatalabClient:
|
|
|
1406
1675
|
file_url: Optional[str] = None,
|
|
1407
1676
|
options: Optional[SegmentOptions] = None,
|
|
1408
1677
|
save_output: Optional[Union[str, Path]] = None,
|
|
1678
|
+
stream_response_to: Optional[Union[str, Path]] = None,
|
|
1409
1679
|
max_polls: int = 300,
|
|
1410
1680
|
poll_interval: int = 1,
|
|
1411
|
-
) -> ConversionResult:
|
|
1681
|
+
) -> Union[ConversionResult, FileResult]:
|
|
1412
1682
|
"""
|
|
1413
1683
|
Segment a document into sections using a schema (sync version)
|
|
1414
1684
|
|
|
@@ -1417,6 +1687,7 @@ class DatalabClient:
|
|
|
1417
1687
|
file_url: URL of the file to segment
|
|
1418
1688
|
options: Segmentation options (must include segmentation_schema)
|
|
1419
1689
|
save_output: Optional path to save output files
|
|
1690
|
+
stream_response_to: Optional path to stream raw JSON response to disk
|
|
1420
1691
|
max_polls: Maximum number of polling attempts
|
|
1421
1692
|
poll_interval: Seconds between polling attempts
|
|
1422
1693
|
"""
|
|
@@ -1426,6 +1697,7 @@ class DatalabClient:
|
|
|
1426
1697
|
file_url=file_url,
|
|
1427
1698
|
options=options,
|
|
1428
1699
|
save_output=save_output,
|
|
1700
|
+
stream_response_to=stream_response_to,
|
|
1429
1701
|
max_polls=max_polls,
|
|
1430
1702
|
poll_interval=poll_interval,
|
|
1431
1703
|
)
|
|
@@ -1437,9 +1709,10 @@ class DatalabClient:
|
|
|
1437
1709
|
file_url: Optional[str] = None,
|
|
1438
1710
|
options: Optional[CustomPipelineOptions] = None,
|
|
1439
1711
|
save_output: Optional[Union[str, Path]] = None,
|
|
1712
|
+
stream_response_to: Optional[Union[str, Path]] = None,
|
|
1440
1713
|
max_polls: int = 300,
|
|
1441
1714
|
poll_interval: int = 1,
|
|
1442
|
-
) -> ConversionResult:
|
|
1715
|
+
) -> Union[ConversionResult, FileResult]:
|
|
1443
1716
|
"""
|
|
1444
1717
|
Execute a custom pipeline configuration (sync version)
|
|
1445
1718
|
|
|
@@ -1448,6 +1721,7 @@ class DatalabClient:
|
|
|
1448
1721
|
file_url: URL of the file to process
|
|
1449
1722
|
options: Custom pipeline options (must include pipeline_id)
|
|
1450
1723
|
save_output: Optional path to save output files
|
|
1724
|
+
stream_response_to: Optional path to stream raw JSON response to disk
|
|
1451
1725
|
max_polls: Maximum number of polling attempts
|
|
1452
1726
|
poll_interval: Seconds between polling attempts
|
|
1453
1727
|
"""
|
|
@@ -1457,6 +1731,7 @@ class DatalabClient:
|
|
|
1457
1731
|
file_url=file_url,
|
|
1458
1732
|
options=options,
|
|
1459
1733
|
save_output=save_output,
|
|
1734
|
+
stream_response_to=stream_response_to,
|
|
1460
1735
|
max_polls=max_polls,
|
|
1461
1736
|
poll_interval=poll_interval,
|
|
1462
1737
|
)
|
|
@@ -1468,9 +1743,10 @@ class DatalabClient:
|
|
|
1468
1743
|
file_url: Optional[str] = None,
|
|
1469
1744
|
options: Optional[TrackChangesOptions] = None,
|
|
1470
1745
|
save_output: Optional[Union[str, Path]] = None,
|
|
1746
|
+
stream_response_to: Optional[Union[str, Path]] = None,
|
|
1471
1747
|
max_polls: int = 300,
|
|
1472
1748
|
poll_interval: int = 1,
|
|
1473
|
-
) -> ConversionResult:
|
|
1749
|
+
) -> Union[ConversionResult, FileResult]:
|
|
1474
1750
|
"""
|
|
1475
1751
|
Extract and display tracked changes from DOCX documents (sync version)
|
|
1476
1752
|
|
|
@@ -1479,6 +1755,7 @@ class DatalabClient:
|
|
|
1479
1755
|
file_url: URL of the DOCX file
|
|
1480
1756
|
options: Track changes options
|
|
1481
1757
|
save_output: Optional path to save output files
|
|
1758
|
+
stream_response_to: Optional path to stream raw JSON response to disk
|
|
1482
1759
|
max_polls: Maximum number of polling attempts
|
|
1483
1760
|
poll_interval: Seconds between polling attempts
|
|
1484
1761
|
"""
|
|
@@ -1488,6 +1765,7 @@ class DatalabClient:
|
|
|
1488
1765
|
file_url=file_url,
|
|
1489
1766
|
options=options,
|
|
1490
1767
|
save_output=save_output,
|
|
1768
|
+
stream_response_to=stream_response_to,
|
|
1491
1769
|
max_polls=max_polls,
|
|
1492
1770
|
poll_interval=poll_interval,
|
|
1493
1771
|
)
|
|
@@ -1499,9 +1777,10 @@ class DatalabClient:
|
|
|
1499
1777
|
output_format: str = "docx",
|
|
1500
1778
|
webhook_url: Optional[str] = None,
|
|
1501
1779
|
save_output: Optional[Union[str, Path]] = None,
|
|
1780
|
+
stream_response_to: Optional[Union[str, Path]] = None,
|
|
1502
1781
|
max_polls: int = 300,
|
|
1503
1782
|
poll_interval: int = 1,
|
|
1504
|
-
) -> CreateDocumentResult:
|
|
1783
|
+
) -> Union[CreateDocumentResult, FileResult]:
|
|
1505
1784
|
"""
|
|
1506
1785
|
Create a DOCX document from markdown (sync version)
|
|
1507
1786
|
|
|
@@ -1510,6 +1789,7 @@ class DatalabClient:
|
|
|
1510
1789
|
output_format: Output format (currently only 'docx')
|
|
1511
1790
|
webhook_url: Optional webhook URL for completion notification
|
|
1512
1791
|
save_output: Optional path to save the output file
|
|
1792
|
+
stream_response_to: Optional path to stream raw JSON response to disk
|
|
1513
1793
|
max_polls: Maximum number of polling attempts
|
|
1514
1794
|
poll_interval: Seconds between polling attempts
|
|
1515
1795
|
"""
|
|
@@ -1519,6 +1799,7 @@ class DatalabClient:
|
|
|
1519
1799
|
output_format=output_format,
|
|
1520
1800
|
webhook_url=webhook_url,
|
|
1521
1801
|
save_output=save_output,
|
|
1802
|
+
stream_response_to=stream_response_to,
|
|
1522
1803
|
max_polls=max_polls,
|
|
1523
1804
|
poll_interval=poll_interval,
|
|
1524
1805
|
)
|
|
@@ -1529,9 +1810,10 @@ class DatalabClient:
|
|
|
1529
1810
|
file_path: Union[str, Path],
|
|
1530
1811
|
options: Optional[ProcessingOptions] = None,
|
|
1531
1812
|
save_output: Optional[Union[str, Path]] = None,
|
|
1813
|
+
stream_response_to: Optional[Union[str, Path]] = None,
|
|
1532
1814
|
max_polls: int = 300,
|
|
1533
1815
|
poll_interval: int = 1,
|
|
1534
|
-
) -> OCRResult:
|
|
1816
|
+
) -> Union[OCRResult, FileResult]:
|
|
1535
1817
|
"""Perform OCR on a document (sync version)
|
|
1536
1818
|
|
|
1537
1819
|
.. deprecated::
|
|
@@ -1542,6 +1824,7 @@ class DatalabClient:
|
|
|
1542
1824
|
file_path=file_path,
|
|
1543
1825
|
options=options,
|
|
1544
1826
|
save_output=save_output,
|
|
1827
|
+
stream_response_to=stream_response_to,
|
|
1545
1828
|
max_polls=max_polls,
|
|
1546
1829
|
poll_interval=poll_interval,
|
|
1547
1830
|
)
|
|
@@ -1553,9 +1836,10 @@ class DatalabClient:
|
|
|
1553
1836
|
file_url: Optional[str] = None,
|
|
1554
1837
|
options: Optional[FormFillingOptions] = None,
|
|
1555
1838
|
save_output: Optional[Union[str, Path]] = None,
|
|
1839
|
+
stream_response_to: Optional[Union[str, Path]] = None,
|
|
1556
1840
|
max_polls: int = 300,
|
|
1557
1841
|
poll_interval: int = 1,
|
|
1558
|
-
) -> FormFillingResult:
|
|
1842
|
+
) -> Union[FormFillingResult, FileResult]:
|
|
1559
1843
|
"""
|
|
1560
1844
|
Fill PDF or image forms with provided field data (sync version)
|
|
1561
1845
|
|
|
@@ -1564,6 +1848,7 @@ class DatalabClient:
|
|
|
1564
1848
|
file_url: URL of the file to fill
|
|
1565
1849
|
options: Form filling options (must include field_data)
|
|
1566
1850
|
save_output: Optional path to save output files
|
|
1851
|
+
stream_response_to: Optional path to stream raw JSON response to disk
|
|
1567
1852
|
max_polls: Maximum number of polling attempts
|
|
1568
1853
|
poll_interval: Seconds between polling attempts
|
|
1569
1854
|
"""
|
|
@@ -1573,6 +1858,7 @@ class DatalabClient:
|
|
|
1573
1858
|
file_url=file_url,
|
|
1574
1859
|
options=options,
|
|
1575
1860
|
save_output=save_output,
|
|
1861
|
+
stream_response_to=stream_response_to,
|
|
1576
1862
|
max_polls=max_polls,
|
|
1577
1863
|
poll_interval=poll_interval,
|
|
1578
1864
|
)
|
datalab_sdk/models.py
CHANGED
|
@@ -498,3 +498,14 @@ class CreateDocumentResult:
|
|
|
498
498
|
|
|
499
499
|
with open(output_path, "wb") as f:
|
|
500
500
|
f.write(base64.b64decode(self.output_base64))
|
|
501
|
+
|
|
502
|
+
|
|
503
|
+
@dataclass
|
|
504
|
+
class FileResult:
|
|
505
|
+
"""Lightweight result returned when stream_response_to is used.
|
|
506
|
+
The full JSON response is written directly to disk at output_path,
|
|
507
|
+
never fully loaded into memory."""
|
|
508
|
+
success: bool
|
|
509
|
+
status: str
|
|
510
|
+
output_path: Path
|
|
511
|
+
error: Optional[str] = None
|
datalab_sdk/settings.py
CHANGED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
datalab_sdk/__init__.py,sha256=KjPwAikE20IeuZHKhLENi4Aqrb9IpJV63nwNh8vB0so,1256
|
|
2
|
-
datalab_sdk/cli.py,sha256=NELgNZstpBrhPoQHqsI67kNRYew_nJpq23_ENsWvmGY,38859
|
|
3
|
-
datalab_sdk/client.py,sha256=zTY0_javpBQb8oJcNUoMqvbfkp2JkgWxo5m_TzZ7u4Y,61454
|
|
4
|
-
datalab_sdk/exceptions.py,sha256=MDfNd-l152OUVhZSfEsE95McJq-IuOsrEsEQ4CRMbEI,785
|
|
5
|
-
datalab_sdk/mimetypes.py,sha256=a4ULJmHxoR_RMsD0j51hx0t2Q7In_PzNm7UlWX07eEE,932
|
|
6
|
-
datalab_sdk/models.py,sha256=RA3AaBgAiLHv2P9VibBbK7XUzpGPe8VBtB3axnYz7dw,16811
|
|
7
|
-
datalab_sdk/settings.py,sha256=fGAqE-Kb7LUtz9wlDrQklWxQlQTiz8ilD4iRMT1xwyg,365
|
|
8
|
-
datalab_python_sdk-0.3.0.dist-info/METADATA,sha256=Wf3x0RZTVDvi-47Ef9skUL4NO_5VKOwGcJcLqK9LGgY,2210
|
|
9
|
-
datalab_python_sdk-0.3.0.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
|
|
10
|
-
datalab_python_sdk-0.3.0.dist-info/entry_points.txt,sha256=rqWxO21UV57JxxyeF20iBTxHpzBYOA69hCHIqwdn-Ok,48
|
|
11
|
-
datalab_python_sdk-0.3.0.dist-info/licenses/LICENSE,sha256=XGjT-Uz6t7UZzr3JCZfilsGcZEgMm_1aONcRunohxWg,1064
|
|
12
|
-
datalab_python_sdk-0.3.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|