chunkr-ai 0.1.0a2__py3-none-any.whl → 0.1.0a4__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.
- chunkr_ai/__init__.py +3 -0
- chunkr_ai/_client.py +18 -10
- chunkr_ai/_files.py +1 -1
- chunkr_ai/_version.py +1 -1
- chunkr_ai/lib/tasks_poll.py +122 -0
- chunkr_ai/pagination.py +61 -1
- chunkr_ai/resources/__init__.py +27 -13
- chunkr_ai/resources/files.py +712 -0
- chunkr_ai/resources/{task → tasks}/__init__.py +14 -14
- chunkr_ai/resources/{task → tasks}/parse.py +48 -52
- chunkr_ai/resources/{task/task.py → tasks/tasks.py} +58 -126
- chunkr_ai/types/__init__.py +7 -0
- chunkr_ai/types/delete.py +10 -0
- chunkr_ai/types/file.py +30 -0
- chunkr_ai/types/file_create_params.py +17 -0
- chunkr_ai/types/file_list_params.py +28 -0
- chunkr_ai/types/file_url.py +15 -0
- chunkr_ai/types/file_url_params.py +15 -0
- chunkr_ai/types/files_list_response.py +20 -0
- chunkr_ai/types/{task/task.py → task.py} +55 -23
- chunkr_ai/types/{task → tasks}/__init__.py +0 -1
- chunkr_ai/types/{task → tasks}/parse_create_params.py +61 -23
- chunkr_ai/types/{task → tasks}/parse_update_params.py +54 -22
- {chunkr_ai-0.1.0a2.dist-info → chunkr_ai-0.1.0a4.dist-info}/METADATA +38 -20
- chunkr_ai-0.1.0a4.dist-info/RECORD +53 -0
- chunkr_ai-0.1.0a2.dist-info/RECORD +0 -44
- {chunkr_ai-0.1.0a2.dist-info → chunkr_ai-0.1.0a4.dist-info}/WHEEL +0 -0
- {chunkr_ai-0.1.0a2.dist-info → chunkr_ai-0.1.0a4.dist-info}/licenses/LICENSE +0 -0
chunkr_ai/__init__.py
CHANGED
@@ -72,6 +72,9 @@ __all__ = [
|
|
72
72
|
]
|
73
73
|
|
74
74
|
if not _t.TYPE_CHECKING:
|
75
|
+
# Load custom helpers that monkey-patch generated types.
|
76
|
+
# This keeps custom code separate from generated files, per Stainless guidance.
|
77
|
+
from .lib import tasks_poll as _tasks_poll # noqa: F401
|
75
78
|
from ._utils._resources_proxy import resources as resources
|
76
79
|
|
77
80
|
_setup_logging()
|
chunkr_ai/_client.py
CHANGED
@@ -21,7 +21,7 @@ from ._types import (
|
|
21
21
|
)
|
22
22
|
from ._utils import is_given, get_async_library
|
23
23
|
from ._version import __version__
|
24
|
-
from .resources import health
|
24
|
+
from .resources import files, health
|
25
25
|
from ._streaming import Stream as Stream, AsyncStream as AsyncStream
|
26
26
|
from ._exceptions import ChunkrError, APIStatusError
|
27
27
|
from ._base_client import (
|
@@ -29,13 +29,14 @@ from ._base_client import (
|
|
29
29
|
SyncAPIClient,
|
30
30
|
AsyncAPIClient,
|
31
31
|
)
|
32
|
-
from .resources.
|
32
|
+
from .resources.tasks import tasks
|
33
33
|
|
34
34
|
__all__ = ["Timeout", "Transport", "ProxiesTypes", "RequestOptions", "Chunkr", "AsyncChunkr", "Client", "AsyncClient"]
|
35
35
|
|
36
36
|
|
37
37
|
class Chunkr(SyncAPIClient):
|
38
|
-
|
38
|
+
tasks: tasks.TasksResource
|
39
|
+
files: files.FilesResource
|
39
40
|
health: health.HealthResource
|
40
41
|
with_raw_response: ChunkrWithRawResponse
|
41
42
|
with_streaming_response: ChunkrWithStreamedResponse
|
@@ -94,7 +95,8 @@ class Chunkr(SyncAPIClient):
|
|
94
95
|
_strict_response_validation=_strict_response_validation,
|
95
96
|
)
|
96
97
|
|
97
|
-
self.
|
98
|
+
self.tasks = tasks.TasksResource(self)
|
99
|
+
self.files = files.FilesResource(self)
|
98
100
|
self.health = health.HealthResource(self)
|
99
101
|
self.with_raw_response = ChunkrWithRawResponse(self)
|
100
102
|
self.with_streaming_response = ChunkrWithStreamedResponse(self)
|
@@ -205,7 +207,8 @@ class Chunkr(SyncAPIClient):
|
|
205
207
|
|
206
208
|
|
207
209
|
class AsyncChunkr(AsyncAPIClient):
|
208
|
-
|
210
|
+
tasks: tasks.AsyncTasksResource
|
211
|
+
files: files.AsyncFilesResource
|
209
212
|
health: health.AsyncHealthResource
|
210
213
|
with_raw_response: AsyncChunkrWithRawResponse
|
211
214
|
with_streaming_response: AsyncChunkrWithStreamedResponse
|
@@ -264,7 +267,8 @@ class AsyncChunkr(AsyncAPIClient):
|
|
264
267
|
_strict_response_validation=_strict_response_validation,
|
265
268
|
)
|
266
269
|
|
267
|
-
self.
|
270
|
+
self.tasks = tasks.AsyncTasksResource(self)
|
271
|
+
self.files = files.AsyncFilesResource(self)
|
268
272
|
self.health = health.AsyncHealthResource(self)
|
269
273
|
self.with_raw_response = AsyncChunkrWithRawResponse(self)
|
270
274
|
self.with_streaming_response = AsyncChunkrWithStreamedResponse(self)
|
@@ -376,25 +380,29 @@ class AsyncChunkr(AsyncAPIClient):
|
|
376
380
|
|
377
381
|
class ChunkrWithRawResponse:
|
378
382
|
def __init__(self, client: Chunkr) -> None:
|
379
|
-
self.
|
383
|
+
self.tasks = tasks.TasksResourceWithRawResponse(client.tasks)
|
384
|
+
self.files = files.FilesResourceWithRawResponse(client.files)
|
380
385
|
self.health = health.HealthResourceWithRawResponse(client.health)
|
381
386
|
|
382
387
|
|
383
388
|
class AsyncChunkrWithRawResponse:
|
384
389
|
def __init__(self, client: AsyncChunkr) -> None:
|
385
|
-
self.
|
390
|
+
self.tasks = tasks.AsyncTasksResourceWithRawResponse(client.tasks)
|
391
|
+
self.files = files.AsyncFilesResourceWithRawResponse(client.files)
|
386
392
|
self.health = health.AsyncHealthResourceWithRawResponse(client.health)
|
387
393
|
|
388
394
|
|
389
395
|
class ChunkrWithStreamedResponse:
|
390
396
|
def __init__(self, client: Chunkr) -> None:
|
391
|
-
self.
|
397
|
+
self.tasks = tasks.TasksResourceWithStreamingResponse(client.tasks)
|
398
|
+
self.files = files.FilesResourceWithStreamingResponse(client.files)
|
392
399
|
self.health = health.HealthResourceWithStreamingResponse(client.health)
|
393
400
|
|
394
401
|
|
395
402
|
class AsyncChunkrWithStreamedResponse:
|
396
403
|
def __init__(self, client: AsyncChunkr) -> None:
|
397
|
-
self.
|
404
|
+
self.tasks = tasks.AsyncTasksResourceWithStreamingResponse(client.tasks)
|
405
|
+
self.files = files.AsyncFilesResourceWithStreamingResponse(client.files)
|
398
406
|
self.health = health.AsyncHealthResourceWithStreamingResponse(client.health)
|
399
407
|
|
400
408
|
|
chunkr_ai/_files.py
CHANGED
@@ -34,7 +34,7 @@ def assert_is_file_content(obj: object, *, key: str | None = None) -> None:
|
|
34
34
|
if not is_file_content(obj):
|
35
35
|
prefix = f"Expected entry at `{key}`" if key is not None else f"Expected file input `{obj!r}`"
|
36
36
|
raise RuntimeError(
|
37
|
-
f"{prefix} to be bytes, an io.IOBase instance, PathLike or a tuple but received {type(obj)} instead."
|
37
|
+
f"{prefix} to be bytes, an io.IOBase instance, PathLike or a tuple but received {type(obj)} instead. See https://github.com/lumina-ai-inc/chunkr-python/tree/main#file-uploads"
|
38
38
|
) from None
|
39
39
|
|
40
40
|
|
chunkr_ai/_version.py
CHANGED
@@ -0,0 +1,122 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
"""
|
4
|
+
Custom helpers for task polling.
|
5
|
+
|
6
|
+
This module adds `Task.poll()` and `Task.apoll()` methods at runtime to the
|
7
|
+
generated `Task` model, without modifying generated code directly.
|
8
|
+
|
9
|
+
Usage:
|
10
|
+
task = client.tasks.get(task_id)
|
11
|
+
task = task.poll(client) # blocks until terminal state
|
12
|
+
|
13
|
+
# async
|
14
|
+
task = await async_client.tasks.get(task_id)
|
15
|
+
task = await task.apoll(async_client)
|
16
|
+
"""
|
17
|
+
|
18
|
+
import time
|
19
|
+
import asyncio
|
20
|
+
from typing import Protocol, cast
|
21
|
+
|
22
|
+
from .._types import NOT_GIVEN, NotGiven
|
23
|
+
from .._client import Chunkr, AsyncChunkr
|
24
|
+
from ..types.task import Task as _Task
|
25
|
+
from .._exceptions import ChunkrError
|
26
|
+
|
27
|
+
TERMINAL_STATUSES = {"Succeeded", "Failed", "Cancelled"}
|
28
|
+
|
29
|
+
|
30
|
+
def _task_poll(
|
31
|
+
self: _Task,
|
32
|
+
client: Chunkr,
|
33
|
+
*,
|
34
|
+
interval: float = 0.5,
|
35
|
+
timeout: float = 600.0,
|
36
|
+
include_chunks: bool | NotGiven = NOT_GIVEN,
|
37
|
+
base64_urls: bool | NotGiven = NOT_GIVEN,
|
38
|
+
) -> _Task:
|
39
|
+
"""Poll the task until it reaches a terminal status.
|
40
|
+
|
41
|
+
Args:
|
42
|
+
client: Synchronous Chunkr client instance.
|
43
|
+
interval: Seconds to sleep between polls.
|
44
|
+
timeout: Maximum total seconds to wait before raising an error.
|
45
|
+
include_chunks: Whether to include chunks in the output response for each poll.
|
46
|
+
base64_urls: Whether to return base64 encoded URLs.
|
47
|
+
"""
|
48
|
+
start_time = time.monotonic()
|
49
|
+
current: _Task = self
|
50
|
+
|
51
|
+
class _TasksGetProtocol(Protocol):
|
52
|
+
def get(
|
53
|
+
self,
|
54
|
+
task_id: str,
|
55
|
+
*,
|
56
|
+
base64_urls: bool | NotGiven = NOT_GIVEN,
|
57
|
+
include_chunks: bool | NotGiven = NOT_GIVEN,
|
58
|
+
) -> _Task: ...
|
59
|
+
|
60
|
+
resource = cast(_TasksGetProtocol, client.tasks)
|
61
|
+
|
62
|
+
while current.status not in TERMINAL_STATUSES:
|
63
|
+
if time.monotonic() - start_time > timeout:
|
64
|
+
raise ChunkrError("Task polling timed out.")
|
65
|
+
|
66
|
+
if interval > 0:
|
67
|
+
time.sleep(interval)
|
68
|
+
|
69
|
+
current = resource.get(
|
70
|
+
current.task_id,
|
71
|
+
include_chunks=include_chunks,
|
72
|
+
base64_urls=base64_urls,
|
73
|
+
)
|
74
|
+
|
75
|
+
return current
|
76
|
+
|
77
|
+
|
78
|
+
async def _task_apoll(
|
79
|
+
self: _Task,
|
80
|
+
client: AsyncChunkr,
|
81
|
+
*,
|
82
|
+
interval: float = 0.5,
|
83
|
+
timeout: float = 600.0,
|
84
|
+
include_chunks: bool | NotGiven = NOT_GIVEN,
|
85
|
+
base64_urls: bool | NotGiven = NOT_GIVEN,
|
86
|
+
) -> _Task:
|
87
|
+
"""Async poll the task until it reaches a terminal status."""
|
88
|
+
start_time = time.monotonic()
|
89
|
+
current: _Task = self
|
90
|
+
|
91
|
+
class _AsyncTasksGetProtocol(Protocol):
|
92
|
+
async def get(
|
93
|
+
self,
|
94
|
+
task_id: str,
|
95
|
+
*,
|
96
|
+
base64_urls: bool | NotGiven = NOT_GIVEN,
|
97
|
+
include_chunks: bool | NotGiven = NOT_GIVEN,
|
98
|
+
) -> _Task: ...
|
99
|
+
|
100
|
+
aresource = cast(_AsyncTasksGetProtocol, client.tasks)
|
101
|
+
|
102
|
+
while current.status not in TERMINAL_STATUSES:
|
103
|
+
if time.monotonic() - start_time > timeout:
|
104
|
+
raise ChunkrError("Task polling timed out.")
|
105
|
+
|
106
|
+
if interval > 0:
|
107
|
+
await asyncio.sleep(interval)
|
108
|
+
|
109
|
+
current = await aresource.get(
|
110
|
+
current.task_id,
|
111
|
+
include_chunks=include_chunks,
|
112
|
+
base64_urls=base64_urls,
|
113
|
+
)
|
114
|
+
|
115
|
+
return current
|
116
|
+
|
117
|
+
|
118
|
+
# Attach methods to the generated Task model
|
119
|
+
_Task.poll = _task_poll # type: ignore[attr-defined]
|
120
|
+
_Task.apoll = _task_apoll # type: ignore[attr-defined]
|
121
|
+
|
122
|
+
|
chunkr_ai/pagination.py
CHANGED
@@ -6,7 +6,7 @@ from typing_extensions import override
|
|
6
6
|
|
7
7
|
from ._base_client import BasePage, PageInfo, BaseSyncPage, BaseAsyncPage
|
8
8
|
|
9
|
-
__all__ = ["SyncTasksPage", "AsyncTasksPage"]
|
9
|
+
__all__ = ["SyncTasksPage", "AsyncTasksPage", "SyncFilesPage", "AsyncFilesPage"]
|
10
10
|
|
11
11
|
_T = TypeVar("_T")
|
12
12
|
|
@@ -69,3 +69,63 @@ class AsyncTasksPage(BaseAsyncPage[_T], BasePage[_T], Generic[_T]):
|
|
69
69
|
return None
|
70
70
|
|
71
71
|
return PageInfo(params={"cursor": next_cursor})
|
72
|
+
|
73
|
+
|
74
|
+
class SyncFilesPage(BaseSyncPage[_T], BasePage[_T], Generic[_T]):
|
75
|
+
files: List[_T]
|
76
|
+
next_cursor: Optional[datetime] = None
|
77
|
+
has_more: Optional[bool] = None
|
78
|
+
"""Whether there are more pages available"""
|
79
|
+
|
80
|
+
@override
|
81
|
+
def _get_page_items(self) -> List[_T]:
|
82
|
+
files = self.files
|
83
|
+
if not files:
|
84
|
+
return []
|
85
|
+
return files
|
86
|
+
|
87
|
+
@override
|
88
|
+
def has_next_page(self) -> bool:
|
89
|
+
has_more = self.has_more
|
90
|
+
if has_more is not None and has_more is False:
|
91
|
+
return False
|
92
|
+
|
93
|
+
return super().has_next_page()
|
94
|
+
|
95
|
+
@override
|
96
|
+
def next_page_info(self) -> Optional[PageInfo]:
|
97
|
+
next_cursor = self.next_cursor
|
98
|
+
if not next_cursor:
|
99
|
+
return None
|
100
|
+
|
101
|
+
return PageInfo(params={"cursor": next_cursor})
|
102
|
+
|
103
|
+
|
104
|
+
class AsyncFilesPage(BaseAsyncPage[_T], BasePage[_T], Generic[_T]):
|
105
|
+
files: List[_T]
|
106
|
+
next_cursor: Optional[datetime] = None
|
107
|
+
has_more: Optional[bool] = None
|
108
|
+
"""Whether there are more pages available"""
|
109
|
+
|
110
|
+
@override
|
111
|
+
def _get_page_items(self) -> List[_T]:
|
112
|
+
files = self.files
|
113
|
+
if not files:
|
114
|
+
return []
|
115
|
+
return files
|
116
|
+
|
117
|
+
@override
|
118
|
+
def has_next_page(self) -> bool:
|
119
|
+
has_more = self.has_more
|
120
|
+
if has_more is not None and has_more is False:
|
121
|
+
return False
|
122
|
+
|
123
|
+
return super().has_next_page()
|
124
|
+
|
125
|
+
@override
|
126
|
+
def next_page_info(self) -> Optional[PageInfo]:
|
127
|
+
next_cursor = self.next_cursor
|
128
|
+
if not next_cursor:
|
129
|
+
return None
|
130
|
+
|
131
|
+
return PageInfo(params={"cursor": next_cursor})
|
chunkr_ai/resources/__init__.py
CHANGED
@@ -1,12 +1,20 @@
|
|
1
1
|
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
2
2
|
|
3
|
-
from .
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
3
|
+
from .files import (
|
4
|
+
FilesResource,
|
5
|
+
AsyncFilesResource,
|
6
|
+
FilesResourceWithRawResponse,
|
7
|
+
AsyncFilesResourceWithRawResponse,
|
8
|
+
FilesResourceWithStreamingResponse,
|
9
|
+
AsyncFilesResourceWithStreamingResponse,
|
10
|
+
)
|
11
|
+
from .tasks import (
|
12
|
+
TasksResource,
|
13
|
+
AsyncTasksResource,
|
14
|
+
TasksResourceWithRawResponse,
|
15
|
+
AsyncTasksResourceWithRawResponse,
|
16
|
+
TasksResourceWithStreamingResponse,
|
17
|
+
AsyncTasksResourceWithStreamingResponse,
|
10
18
|
)
|
11
19
|
from .health import (
|
12
20
|
HealthResource,
|
@@ -18,12 +26,18 @@ from .health import (
|
|
18
26
|
)
|
19
27
|
|
20
28
|
__all__ = [
|
21
|
-
"
|
22
|
-
"
|
23
|
-
"
|
24
|
-
"
|
25
|
-
"
|
26
|
-
"
|
29
|
+
"TasksResource",
|
30
|
+
"AsyncTasksResource",
|
31
|
+
"TasksResourceWithRawResponse",
|
32
|
+
"AsyncTasksResourceWithRawResponse",
|
33
|
+
"TasksResourceWithStreamingResponse",
|
34
|
+
"AsyncTasksResourceWithStreamingResponse",
|
35
|
+
"FilesResource",
|
36
|
+
"AsyncFilesResource",
|
37
|
+
"FilesResourceWithRawResponse",
|
38
|
+
"AsyncFilesResourceWithRawResponse",
|
39
|
+
"FilesResourceWithStreamingResponse",
|
40
|
+
"AsyncFilesResourceWithStreamingResponse",
|
27
41
|
"HealthResource",
|
28
42
|
"AsyncHealthResource",
|
29
43
|
"HealthResourceWithRawResponse",
|