retab 0.0.84__tar.gz → 0.0.86__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.
- {retab-0.0.84 → retab-0.0.86}/PKG-INFO +1 -1
- retab-0.0.86/retab/resources/edit/agent/__init__.py +4 -0
- {retab-0.0.84/retab/resources/edit → retab-0.0.86/retab/resources/edit/agent}/client.py +32 -40
- retab-0.0.86/retab/resources/edit/client.py +41 -0
- {retab-0.0.84 → retab-0.0.86}/retab/resources/edit/templates/client.py +10 -0
- retab-0.0.86/retab/resources/workflows/client.py +28 -0
- retab-0.0.86/retab/resources/workflows/runs/__init__.py +3 -0
- {retab-0.0.84/retab/resources/workflows → retab-0.0.86/retab/resources/workflows/runs}/client.py +26 -26
- {retab-0.0.84 → retab-0.0.86}/retab/types/documents/edit.py +8 -2
- {retab-0.0.84 → retab-0.0.86}/retab/types/edit/templates.py +2 -1
- {retab-0.0.84 → retab-0.0.86}/retab.egg-info/PKG-INFO +1 -1
- {retab-0.0.84 → retab-0.0.86}/retab.egg-info/SOURCES.txt +4 -0
- {retab-0.0.84 → retab-0.0.86}/setup.py +1 -1
- {retab-0.0.84 → retab-0.0.86}/README.md +0 -0
- {retab-0.0.84 → retab-0.0.86}/pyproject.toml +0 -0
- {retab-0.0.84 → retab-0.0.86}/retab/__init__.py +0 -0
- {retab-0.0.84 → retab-0.0.86}/retab/_resource.py +0 -0
- {retab-0.0.84 → retab-0.0.86}/retab/client.py +0 -0
- {retab-0.0.84 → retab-0.0.86}/retab/generate_types.py +0 -0
- {retab-0.0.84 → retab-0.0.86}/retab/py.typed +0 -0
- {retab-0.0.84 → retab-0.0.86}/retab/resources/__init__.py +0 -0
- {retab-0.0.84 → retab-0.0.86}/retab/resources/documents/__init__.py +0 -0
- {retab-0.0.84 → retab-0.0.86}/retab/resources/documents/client.py +0 -0
- {retab-0.0.84 → retab-0.0.86}/retab/resources/edit/__init__.py +0 -0
- {retab-0.0.84 → retab-0.0.86}/retab/resources/edit/templates/__init__.py +0 -0
- {retab-0.0.84 → retab-0.0.86}/retab/resources/extractions/__init__.py +0 -0
- {retab-0.0.84 → retab-0.0.86}/retab/resources/extractions/client.py +0 -0
- {retab-0.0.84 → retab-0.0.86}/retab/resources/models.py +0 -0
- {retab-0.0.84 → retab-0.0.86}/retab/resources/projects/__init__.py +0 -0
- {retab-0.0.84 → retab-0.0.86}/retab/resources/projects/client.py +0 -0
- {retab-0.0.84 → retab-0.0.86}/retab/resources/schemas.py +0 -0
- {retab-0.0.84 → retab-0.0.86}/retab/resources/workflows/__init__.py +0 -0
- {retab-0.0.84 → retab-0.0.86}/retab/types/__init__.py +0 -0
- {retab-0.0.84 → retab-0.0.86}/retab/types/chat.py +0 -0
- {retab-0.0.84 → retab-0.0.86}/retab/types/documents/__init__.py +0 -0
- {retab-0.0.84 → retab-0.0.86}/retab/types/documents/classify.py +0 -0
- {retab-0.0.84 → retab-0.0.86}/retab/types/documents/correct_orientation.py +0 -0
- {retab-0.0.84 → retab-0.0.86}/retab/types/documents/create_messages.py +0 -0
- {retab-0.0.84 → retab-0.0.86}/retab/types/documents/extract.py +0 -0
- {retab-0.0.84 → retab-0.0.86}/retab/types/documents/parse.py +0 -0
- {retab-0.0.84 → retab-0.0.86}/retab/types/documents/split.py +0 -0
- {retab-0.0.84 → retab-0.0.86}/retab/types/edit/__init__.py +0 -0
- {retab-0.0.84 → retab-0.0.86}/retab/types/extractions/__init__.py +0 -0
- {retab-0.0.84 → retab-0.0.86}/retab/types/extractions/types.py +0 -0
- {retab-0.0.84 → retab-0.0.86}/retab/types/inference_settings.py +0 -0
- {retab-0.0.84 → retab-0.0.86}/retab/types/mime.py +0 -0
- {retab-0.0.84 → retab-0.0.86}/retab/types/modality.py +0 -0
- {retab-0.0.84 → retab-0.0.86}/retab/types/pagination.py +0 -0
- {retab-0.0.84 → retab-0.0.86}/retab/types/projects/__init__.py +0 -0
- {retab-0.0.84 → retab-0.0.86}/retab/types/projects/metrics.py +0 -0
- {retab-0.0.84 → retab-0.0.86}/retab/types/projects/model.py +0 -0
- {retab-0.0.84 → retab-0.0.86}/retab/types/projects/predictions.py +0 -0
- {retab-0.0.84 → retab-0.0.86}/retab/types/schemas/__init__.py +0 -0
- {retab-0.0.84 → retab-0.0.86}/retab/types/schemas/chat.py +0 -0
- {retab-0.0.84 → retab-0.0.86}/retab/types/schemas/generate.py +0 -0
- {retab-0.0.84 → retab-0.0.86}/retab/types/schemas/layout.py +0 -0
- {retab-0.0.84 → retab-0.0.86}/retab/types/schemas/model.py +0 -0
- {retab-0.0.84 → retab-0.0.86}/retab/types/schemas/templates.py +0 -0
- {retab-0.0.84 → retab-0.0.86}/retab/types/standards.py +0 -0
- {retab-0.0.84 → retab-0.0.86}/retab/types/workflows/__init__.py +0 -0
- {retab-0.0.84 → retab-0.0.86}/retab/types/workflows/model.py +0 -0
- {retab-0.0.84 → retab-0.0.86}/retab/utils/__init__.py +0 -0
- {retab-0.0.84 → retab-0.0.86}/retab/utils/display.py +0 -0
- {retab-0.0.84 → retab-0.0.86}/retab/utils/hashing.py +0 -0
- {retab-0.0.84 → retab-0.0.86}/retab/utils/json_schema.py +0 -0
- {retab-0.0.84 → retab-0.0.86}/retab/utils/mime.py +0 -0
- {retab-0.0.84 → retab-0.0.86}/retab/utils/stream_context_managers.py +0 -0
- {retab-0.0.84 → retab-0.0.86}/retab.egg-info/dependency_links.txt +0 -0
- {retab-0.0.84 → retab-0.0.86}/retab.egg-info/requires.txt +0 -0
- {retab-0.0.84 → retab-0.0.86}/retab.egg-info/top_level.txt +0 -0
- {retab-0.0.84 → retab-0.0.86}/setup.cfg +0 -0
- {retab-0.0.84 → retab-0.0.86}/tests/test_projects.py +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"""
|
|
2
|
-
Edit SDK client - Wrapper for document editing functionality.
|
|
2
|
+
Agent Edit SDK client - Wrapper for agent-based document editing functionality.
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
5
|
from io import IOBase
|
|
@@ -9,26 +9,26 @@ from typing import Any
|
|
|
9
9
|
import PIL.Image
|
|
10
10
|
from pydantic import HttpUrl
|
|
11
11
|
|
|
12
|
-
from
|
|
13
|
-
from
|
|
14
|
-
from
|
|
12
|
+
from ...._resource import AsyncAPIResource, SyncAPIResource
|
|
13
|
+
from ....utils.mime import prepare_mime_document
|
|
14
|
+
from ....types.documents.edit import (
|
|
15
|
+
EditConfig,
|
|
15
16
|
EditRequest,
|
|
16
17
|
EditResponse,
|
|
17
18
|
)
|
|
18
|
-
from
|
|
19
|
-
from
|
|
20
|
-
from .templates import Templates, AsyncTemplates
|
|
19
|
+
from ....types.mime import MIMEData
|
|
20
|
+
from ....types.standards import PreparedRequest, FieldUnset
|
|
21
21
|
|
|
22
22
|
|
|
23
|
-
class
|
|
24
|
-
"""Shared methods for preparing edit API requests."""
|
|
23
|
+
class BaseAgentMixin:
|
|
24
|
+
"""Shared methods for preparing agent edit API requests."""
|
|
25
25
|
|
|
26
|
-
def
|
|
26
|
+
def _prepare_fill(
|
|
27
27
|
self,
|
|
28
28
|
instructions: str,
|
|
29
29
|
document: Path | str | IOBase | MIMEData | PIL.Image.Image | HttpUrl | None = None,
|
|
30
30
|
model: str = FieldUnset,
|
|
31
|
-
|
|
31
|
+
color: str = FieldUnset,
|
|
32
32
|
**extra_body: Any,
|
|
33
33
|
) -> PreparedRequest:
|
|
34
34
|
request_dict: dict[str, Any] = {
|
|
@@ -41,8 +41,9 @@ class BaseEditMixin:
|
|
|
41
41
|
|
|
42
42
|
if model is not FieldUnset:
|
|
43
43
|
request_dict["model"] = model
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
|
|
45
|
+
if color is not FieldUnset:
|
|
46
|
+
request_dict["config"] = EditConfig(color=color)
|
|
46
47
|
|
|
47
48
|
# Merge any extra fields provided by the caller
|
|
48
49
|
if extra_body:
|
|
@@ -51,24 +52,23 @@ class BaseEditMixin:
|
|
|
51
52
|
edit_request = EditRequest(**request_dict)
|
|
52
53
|
return PreparedRequest(
|
|
53
54
|
method="POST",
|
|
54
|
-
url="/v1/edit/fill
|
|
55
|
+
url="/v1/edit/agent/fill",
|
|
55
56
|
data=edit_request.model_dump(mode="json", exclude_unset=True),
|
|
56
57
|
)
|
|
57
58
|
|
|
58
59
|
|
|
59
|
-
class
|
|
60
|
-
"""Edit API wrapper for synchronous usage."""
|
|
60
|
+
class Agent(SyncAPIResource, BaseAgentMixin):
|
|
61
|
+
"""Agent Edit API wrapper for synchronous usage."""
|
|
61
62
|
|
|
62
63
|
def __init__(self, client: Any) -> None:
|
|
63
64
|
super().__init__(client=client)
|
|
64
|
-
self.templates = Templates(client=client)
|
|
65
65
|
|
|
66
|
-
def
|
|
66
|
+
def fill(
|
|
67
67
|
self,
|
|
68
68
|
instructions: str,
|
|
69
69
|
document: Path | str | IOBase | MIMEData | PIL.Image.Image | HttpUrl | None = None,
|
|
70
70
|
model: str = FieldUnset,
|
|
71
|
-
|
|
71
|
+
color: str = FieldUnset,
|
|
72
72
|
**extra_body: Any,
|
|
73
73
|
) -> EditResponse:
|
|
74
74
|
"""
|
|
@@ -80,16 +80,12 @@ class Edit(SyncAPIResource, BaseEditMixin):
|
|
|
80
80
|
3. LLM-based form filling using the provided instructions
|
|
81
81
|
4. Returns the filled document with form field values populated
|
|
82
82
|
|
|
83
|
-
Either `document` OR `template_id` must be provided, but not both.
|
|
84
|
-
|
|
85
83
|
Args:
|
|
86
84
|
instructions: Instructions describing how to fill the form fields.
|
|
87
85
|
document: The document to edit. Can be a file path (Path or str), file-like object,
|
|
88
|
-
MIMEData, PIL Image, or URL.
|
|
86
|
+
MIMEData, PIL Image, or URL.
|
|
89
87
|
model: The LLM model to use for inference. Defaults to "retab-small".
|
|
90
|
-
|
|
91
|
-
pre-defined form fields and empty PDF. Only works for PDF documents.
|
|
92
|
-
Mutually exclusive with document.
|
|
88
|
+
color: Hex color code for filled text (e.g. "#000080"). Defaults to dark blue.
|
|
93
89
|
|
|
94
90
|
Returns:
|
|
95
91
|
EditResponse: Response containing:
|
|
@@ -105,30 +101,29 @@ class Edit(SyncAPIResource, BaseEditMixin):
|
|
|
105
101
|
- PPTX/PPT: Native editing for presentations
|
|
106
102
|
- XLSX/XLS: Native editing for spreadsheets
|
|
107
103
|
"""
|
|
108
|
-
request = self.
|
|
104
|
+
request = self._prepare_fill(
|
|
109
105
|
instructions=instructions,
|
|
110
106
|
document=document,
|
|
111
107
|
model=model,
|
|
112
|
-
|
|
108
|
+
color=color,
|
|
113
109
|
**extra_body,
|
|
114
110
|
)
|
|
115
111
|
response = self._client._prepared_request(request)
|
|
116
112
|
return EditResponse.model_validate(response)
|
|
117
113
|
|
|
118
114
|
|
|
119
|
-
class
|
|
120
|
-
"""Edit API wrapper for asynchronous usage."""
|
|
115
|
+
class AsyncAgent(AsyncAPIResource, BaseAgentMixin):
|
|
116
|
+
"""Agent Edit API wrapper for asynchronous usage."""
|
|
121
117
|
|
|
122
118
|
def __init__(self, client: Any) -> None:
|
|
123
119
|
super().__init__(client=client)
|
|
124
|
-
self.templates = AsyncTemplates(client=client)
|
|
125
120
|
|
|
126
|
-
async def
|
|
121
|
+
async def fill(
|
|
127
122
|
self,
|
|
128
123
|
instructions: str,
|
|
129
124
|
document: Path | str | IOBase | MIMEData | PIL.Image.Image | HttpUrl | None = None,
|
|
130
125
|
model: str = FieldUnset,
|
|
131
|
-
|
|
126
|
+
color: str = FieldUnset,
|
|
132
127
|
**extra_body: Any,
|
|
133
128
|
) -> EditResponse:
|
|
134
129
|
"""
|
|
@@ -140,16 +135,12 @@ class AsyncEdit(AsyncAPIResource, BaseEditMixin):
|
|
|
140
135
|
3. LLM-based form filling using the provided instructions
|
|
141
136
|
4. Returns the filled document with form field values populated
|
|
142
137
|
|
|
143
|
-
Either `document` OR `template_id` must be provided, but not both.
|
|
144
|
-
|
|
145
138
|
Args:
|
|
146
139
|
instructions: Instructions describing how to fill the form fields.
|
|
147
140
|
document: The document to edit. Can be a file path (Path or str), file-like object,
|
|
148
|
-
MIMEData, PIL Image, or URL.
|
|
141
|
+
MIMEData, PIL Image, or URL.
|
|
149
142
|
model: The LLM model to use for inference. Defaults to "retab-small".
|
|
150
|
-
|
|
151
|
-
pre-defined form fields and empty PDF. Only works for PDF documents.
|
|
152
|
-
Mutually exclusive with document.
|
|
143
|
+
color: Hex color code for filled text (e.g. "#000080"). Defaults to dark blue.
|
|
153
144
|
|
|
154
145
|
Returns:
|
|
155
146
|
EditResponse: Response containing:
|
|
@@ -165,12 +156,13 @@ class AsyncEdit(AsyncAPIResource, BaseEditMixin):
|
|
|
165
156
|
- PPTX/PPT: Native editing for presentations
|
|
166
157
|
- XLSX/XLS: Native editing for spreadsheets
|
|
167
158
|
"""
|
|
168
|
-
request = self.
|
|
159
|
+
request = self._prepare_fill(
|
|
169
160
|
instructions=instructions,
|
|
170
161
|
document=document,
|
|
171
162
|
model=model,
|
|
172
|
-
|
|
163
|
+
color=color,
|
|
173
164
|
**extra_body,
|
|
174
165
|
)
|
|
175
166
|
response = await self._client._prepared_request(request)
|
|
176
167
|
return EditResponse.model_validate(response)
|
|
168
|
+
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Edit SDK client - Wrapper for document editing functionality.
|
|
3
|
+
|
|
4
|
+
Provides access to:
|
|
5
|
+
- edit.agent.fill() - Agent-based document editing (PDF, DOCX, PPTX, XLSX)
|
|
6
|
+
- edit.templates.* - Template-based PDF form filling
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from typing import Any
|
|
10
|
+
|
|
11
|
+
from ..._resource import AsyncAPIResource, SyncAPIResource
|
|
12
|
+
from .templates import Templates, AsyncTemplates
|
|
13
|
+
from .agent import Agent, AsyncAgent
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class Edit(SyncAPIResource):
|
|
17
|
+
"""Edit API wrapper for synchronous usage.
|
|
18
|
+
|
|
19
|
+
Sub-clients:
|
|
20
|
+
agent: Agent-based document editing (fill any document with AI)
|
|
21
|
+
templates: Template-based PDF form filling (for batch processing)
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
def __init__(self, client: Any) -> None:
|
|
25
|
+
super().__init__(client=client)
|
|
26
|
+
self.agent = Agent(client=client)
|
|
27
|
+
self.templates = Templates(client=client)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class AsyncEdit(AsyncAPIResource):
|
|
31
|
+
"""Edit API wrapper for asynchronous usage.
|
|
32
|
+
|
|
33
|
+
Sub-clients:
|
|
34
|
+
agent: Agent-based document editing (fill any document with AI)
|
|
35
|
+
templates: Template-based PDF form filling (for batch processing)
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
def __init__(self, client: Any) -> None:
|
|
39
|
+
super().__init__(client=client)
|
|
40
|
+
self.agent = AsyncAgent(client=client)
|
|
41
|
+
self.templates = AsyncTemplates(client=client)
|
|
@@ -12,6 +12,7 @@ from pydantic import HttpUrl
|
|
|
12
12
|
from ...._resource import AsyncAPIResource, SyncAPIResource
|
|
13
13
|
from ....utils.mime import prepare_mime_document
|
|
14
14
|
from ....types.documents.edit import (
|
|
15
|
+
EditConfig,
|
|
15
16
|
FormField,
|
|
16
17
|
InferFormSchemaRequest,
|
|
17
18
|
InferFormSchemaResponse,
|
|
@@ -163,6 +164,7 @@ class BaseTemplatesMixin:
|
|
|
163
164
|
template_id: str,
|
|
164
165
|
instructions: str,
|
|
165
166
|
model: str = FieldUnset,
|
|
167
|
+
color: str = FieldUnset,
|
|
166
168
|
**extra_body: Any,
|
|
167
169
|
) -> PreparedRequest:
|
|
168
170
|
request_dict: dict[str, Any] = {
|
|
@@ -172,6 +174,8 @@ class BaseTemplatesMixin:
|
|
|
172
174
|
|
|
173
175
|
if model is not FieldUnset:
|
|
174
176
|
request_dict["model"] = model
|
|
177
|
+
if color is not FieldUnset:
|
|
178
|
+
request_dict["config"] = EditConfig(color=color)
|
|
175
179
|
if extra_body:
|
|
176
180
|
request_dict.update(extra_body)
|
|
177
181
|
|
|
@@ -368,6 +372,7 @@ class Templates(SyncAPIResource, BaseTemplatesMixin):
|
|
|
368
372
|
template_id: str,
|
|
369
373
|
instructions: str,
|
|
370
374
|
model: str = FieldUnset,
|
|
375
|
+
color: str = FieldUnset,
|
|
371
376
|
**extra_body: Any,
|
|
372
377
|
) -> EditResponse:
|
|
373
378
|
"""
|
|
@@ -380,6 +385,7 @@ class Templates(SyncAPIResource, BaseTemplatesMixin):
|
|
|
380
385
|
template_id: The template ID to use for filling
|
|
381
386
|
instructions: Instructions describing how to fill the form fields
|
|
382
387
|
model: The LLM model to use for inference (default: "retab-small")
|
|
388
|
+
color: Hex color code for filled text (e.g. "#000080"). Defaults to dark blue.
|
|
383
389
|
|
|
384
390
|
Returns:
|
|
385
391
|
EditResponse: Response containing:
|
|
@@ -395,6 +401,7 @@ class Templates(SyncAPIResource, BaseTemplatesMixin):
|
|
|
395
401
|
template_id=template_id,
|
|
396
402
|
instructions=instructions,
|
|
397
403
|
model=model,
|
|
404
|
+
color=color,
|
|
398
405
|
**extra_body,
|
|
399
406
|
)
|
|
400
407
|
response = self._client._prepared_request(request)
|
|
@@ -586,6 +593,7 @@ class AsyncTemplates(AsyncAPIResource, BaseTemplatesMixin):
|
|
|
586
593
|
template_id: str,
|
|
587
594
|
instructions: str,
|
|
588
595
|
model: str = FieldUnset,
|
|
596
|
+
color: str = FieldUnset,
|
|
589
597
|
**extra_body: Any,
|
|
590
598
|
) -> EditResponse:
|
|
591
599
|
"""
|
|
@@ -598,6 +606,7 @@ class AsyncTemplates(AsyncAPIResource, BaseTemplatesMixin):
|
|
|
598
606
|
template_id: The template ID to use for filling
|
|
599
607
|
instructions: Instructions describing how to fill the form fields
|
|
600
608
|
model: The LLM model to use for inference (default: "retab-small")
|
|
609
|
+
color: Hex color code for filled text (e.g. "#000080"). Defaults to dark blue.
|
|
601
610
|
|
|
602
611
|
Returns:
|
|
603
612
|
EditResponse: Response containing:
|
|
@@ -613,6 +622,7 @@ class AsyncTemplates(AsyncAPIResource, BaseTemplatesMixin):
|
|
|
613
622
|
template_id=template_id,
|
|
614
623
|
instructions=instructions,
|
|
615
624
|
model=model,
|
|
625
|
+
color=color,
|
|
616
626
|
**extra_body,
|
|
617
627
|
)
|
|
618
628
|
response = await self._client._prepared_request(request)
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
|
|
3
|
+
from ..._resource import AsyncAPIResource, SyncAPIResource
|
|
4
|
+
from .runs import WorkflowRuns, AsyncWorkflowRuns
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Workflows(SyncAPIResource):
|
|
8
|
+
"""Workflows API wrapper for synchronous operations.
|
|
9
|
+
|
|
10
|
+
Sub-clients:
|
|
11
|
+
runs: Workflow run operations (create, get)
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
def __init__(self, client: Any) -> None:
|
|
15
|
+
super().__init__(client=client)
|
|
16
|
+
self.runs = WorkflowRuns(client=client)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class AsyncWorkflows(AsyncAPIResource):
|
|
20
|
+
"""Workflows API wrapper for asynchronous operations.
|
|
21
|
+
|
|
22
|
+
Sub-clients:
|
|
23
|
+
runs: Workflow run operations (create, get)
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
def __init__(self, client: Any) -> None:
|
|
27
|
+
super().__init__(client=client)
|
|
28
|
+
self.runs = AsyncWorkflowRuns(client=client)
|
{retab-0.0.84/retab/resources/workflows → retab-0.0.86/retab/resources/workflows/runs}/client.py
RENAMED
|
@@ -5,20 +5,20 @@ from typing import Any, Dict
|
|
|
5
5
|
import PIL.Image
|
|
6
6
|
from pydantic import HttpUrl
|
|
7
7
|
|
|
8
|
-
from
|
|
9
|
-
from
|
|
10
|
-
from
|
|
11
|
-
from
|
|
8
|
+
from ...._resource import AsyncAPIResource, SyncAPIResource
|
|
9
|
+
from ....utils.mime import MIMEData, prepare_mime_document
|
|
10
|
+
from ....types.standards import PreparedRequest
|
|
11
|
+
from ....types.workflows import WorkflowRun
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
# Type alias for document inputs
|
|
15
15
|
DocumentInput = Path | str | bytes | IOBase | MIMEData | PIL.Image.Image | HttpUrl
|
|
16
16
|
|
|
17
17
|
|
|
18
|
-
class
|
|
19
|
-
"""Mixin providing shared methods for workflow operations."""
|
|
18
|
+
class WorkflowRunsMixin:
|
|
19
|
+
"""Mixin providing shared methods for workflow run operations."""
|
|
20
20
|
|
|
21
|
-
def
|
|
21
|
+
def prepare_create(
|
|
22
22
|
self,
|
|
23
23
|
workflow_id: str,
|
|
24
24
|
documents: Dict[str, DocumentInput],
|
|
@@ -33,9 +33,9 @@ class WorkflowsMixin:
|
|
|
33
33
|
|
|
34
34
|
Returns:
|
|
35
35
|
PreparedRequest: The prepared request
|
|
36
|
-
|
|
36
|
+
|
|
37
37
|
Example:
|
|
38
|
-
>>> client.workflows.
|
|
38
|
+
>>> client.workflows.runs.create(
|
|
39
39
|
... workflow_id="wf_abc123",
|
|
40
40
|
... documents={
|
|
41
41
|
... "start-node-1": Path("invoice.pdf"),
|
|
@@ -56,7 +56,7 @@ class WorkflowsMixin:
|
|
|
56
56
|
data = {"documents": documents_payload}
|
|
57
57
|
return PreparedRequest(method="POST", url=f"/v1/workflows/{workflow_id}/run", data=data)
|
|
58
58
|
|
|
59
|
-
def
|
|
59
|
+
def prepare_get(self, run_id: str) -> PreparedRequest:
|
|
60
60
|
"""Prepare a request to get a workflow run by ID.
|
|
61
61
|
|
|
62
62
|
Args:
|
|
@@ -68,13 +68,13 @@ class WorkflowsMixin:
|
|
|
68
68
|
return PreparedRequest(method="GET", url=f"/v1/workflows/runs/{run_id}")
|
|
69
69
|
|
|
70
70
|
|
|
71
|
-
class
|
|
72
|
-
"""
|
|
71
|
+
class WorkflowRuns(SyncAPIResource, WorkflowRunsMixin):
|
|
72
|
+
"""Workflow Runs API wrapper for synchronous operations."""
|
|
73
73
|
|
|
74
74
|
def __init__(self, *args, **kwargs):
|
|
75
75
|
super().__init__(*args, **kwargs)
|
|
76
76
|
|
|
77
|
-
def
|
|
77
|
+
def create(
|
|
78
78
|
self,
|
|
79
79
|
workflow_id: str,
|
|
80
80
|
documents: Dict[str, DocumentInput],
|
|
@@ -82,7 +82,7 @@ class Workflows(SyncAPIResource, WorkflowsMixin):
|
|
|
82
82
|
"""Run a workflow with the provided input documents.
|
|
83
83
|
|
|
84
84
|
This creates a workflow run and starts execution in the background.
|
|
85
|
-
The returned WorkflowRun will have status "running" - use
|
|
85
|
+
The returned WorkflowRun will have status "running" - use get()
|
|
86
86
|
to check for updates on the run status.
|
|
87
87
|
|
|
88
88
|
Args:
|
|
@@ -99,7 +99,7 @@ class Workflows(SyncAPIResource, WorkflowsMixin):
|
|
|
99
99
|
missing input documents for start nodes)
|
|
100
100
|
|
|
101
101
|
Example:
|
|
102
|
-
>>> run = client.workflows.
|
|
102
|
+
>>> run = client.workflows.runs.create(
|
|
103
103
|
... workflow_id="wf_abc123",
|
|
104
104
|
... documents={
|
|
105
105
|
... "start-node-1": Path("invoice.pdf"),
|
|
@@ -108,11 +108,11 @@ class Workflows(SyncAPIResource, WorkflowsMixin):
|
|
|
108
108
|
... )
|
|
109
109
|
>>> print(f"Run started: {run.id}, status: {run.status}")
|
|
110
110
|
"""
|
|
111
|
-
request = self.
|
|
111
|
+
request = self.prepare_create(workflow_id=workflow_id, documents=documents)
|
|
112
112
|
response = self._client._prepared_request(request)
|
|
113
113
|
return WorkflowRun.model_validate(response)
|
|
114
114
|
|
|
115
|
-
def
|
|
115
|
+
def get(self, run_id: str) -> WorkflowRun:
|
|
116
116
|
"""Get a workflow run by ID.
|
|
117
117
|
|
|
118
118
|
Args:
|
|
@@ -124,18 +124,18 @@ class Workflows(SyncAPIResource, WorkflowsMixin):
|
|
|
124
124
|
Raises:
|
|
125
125
|
HTTPException: If the request fails (e.g., run not found)
|
|
126
126
|
"""
|
|
127
|
-
request = self.
|
|
127
|
+
request = self.prepare_get(run_id)
|
|
128
128
|
response = self._client._prepared_request(request)
|
|
129
129
|
return WorkflowRun.model_validate(response)
|
|
130
130
|
|
|
131
131
|
|
|
132
|
-
class
|
|
133
|
-
"""
|
|
132
|
+
class AsyncWorkflowRuns(AsyncAPIResource, WorkflowRunsMixin):
|
|
133
|
+
"""Workflow Runs API wrapper for asynchronous operations."""
|
|
134
134
|
|
|
135
135
|
def __init__(self, *args, **kwargs):
|
|
136
136
|
super().__init__(*args, **kwargs)
|
|
137
137
|
|
|
138
|
-
async def
|
|
138
|
+
async def create(
|
|
139
139
|
self,
|
|
140
140
|
workflow_id: str,
|
|
141
141
|
documents: Dict[str, DocumentInput],
|
|
@@ -143,7 +143,7 @@ class AsyncWorkflows(AsyncAPIResource, WorkflowsMixin):
|
|
|
143
143
|
"""Run a workflow with the provided input documents.
|
|
144
144
|
|
|
145
145
|
This creates a workflow run and starts execution in the background.
|
|
146
|
-
The returned WorkflowRun will have status "running" - use
|
|
146
|
+
The returned WorkflowRun will have status "running" - use get()
|
|
147
147
|
to check for updates on the run status.
|
|
148
148
|
|
|
149
149
|
Args:
|
|
@@ -160,7 +160,7 @@ class AsyncWorkflows(AsyncAPIResource, WorkflowsMixin):
|
|
|
160
160
|
missing input documents for start nodes)
|
|
161
161
|
|
|
162
162
|
Example:
|
|
163
|
-
>>> run = await client.workflows.
|
|
163
|
+
>>> run = await client.workflows.runs.create(
|
|
164
164
|
... workflow_id="wf_abc123",
|
|
165
165
|
... documents={
|
|
166
166
|
... "start-node-1": Path("invoice.pdf"),
|
|
@@ -169,11 +169,11 @@ class AsyncWorkflows(AsyncAPIResource, WorkflowsMixin):
|
|
|
169
169
|
... )
|
|
170
170
|
>>> print(f"Run started: {run.id}, status: {run.status}")
|
|
171
171
|
"""
|
|
172
|
-
request = self.
|
|
172
|
+
request = self.prepare_create(workflow_id=workflow_id, documents=documents)
|
|
173
173
|
response = await self._client._prepared_request(request)
|
|
174
174
|
return WorkflowRun.model_validate(response)
|
|
175
175
|
|
|
176
|
-
async def
|
|
176
|
+
async def get(self, run_id: str) -> WorkflowRun:
|
|
177
177
|
"""Get a workflow run by ID.
|
|
178
178
|
|
|
179
179
|
Args:
|
|
@@ -185,6 +185,6 @@ class AsyncWorkflows(AsyncAPIResource, WorkflowsMixin):
|
|
|
185
185
|
Raises:
|
|
186
186
|
HTTPException: If the request fails (e.g., run not found)
|
|
187
187
|
"""
|
|
188
|
-
request = self.
|
|
188
|
+
request = self.prepare_get(run_id)
|
|
189
189
|
response = await self._client._prepared_request(request)
|
|
190
190
|
return WorkflowRun.model_validate(response)
|
|
@@ -107,10 +107,15 @@ class OCRResult(BaseModel):
|
|
|
107
107
|
class InferFormSchemaRequest(BaseModel):
|
|
108
108
|
"""Request to infer form schema from a PDF or DOCX document."""
|
|
109
109
|
|
|
110
|
-
document: MIMEData = Field(..., description="Input document (PDF
|
|
110
|
+
document: MIMEData = Field(..., description="Input document (PDF, DOCX, XLSX or PPTX).")
|
|
111
111
|
model: str = Field(default="retab-small", description="LLM model to use for inference")
|
|
112
112
|
|
|
113
113
|
|
|
114
|
+
class EditConfig(BaseModel):
|
|
115
|
+
"""Configuration for edit requests."""
|
|
116
|
+
color: str = Field(default="#000080", description="Hex code of the color to use for the filled text")
|
|
117
|
+
|
|
118
|
+
|
|
114
119
|
class EditRequest(BaseModel):
|
|
115
120
|
"""Request for the infer_and_fill_schema endpoint.
|
|
116
121
|
|
|
@@ -118,10 +123,11 @@ class EditRequest(BaseModel):
|
|
|
118
123
|
- When `document` is provided: OCR + LLM inference to detect and fill form fields
|
|
119
124
|
- When `template_id` is provided: Uses pre-defined form fields from the template (PDF only)
|
|
120
125
|
"""
|
|
121
|
-
document: Optional[MIMEData] = Field(default=None, description="Input document (PDF
|
|
126
|
+
document: Optional[MIMEData] = Field(default=None, description="Input document (PDF, DOCX, XLSX or PPTX). Mutually exclusive with template_id.")
|
|
122
127
|
model: str = Field(default="retab-small", description="LLM model to use for inference")
|
|
123
128
|
instructions: str = Field(..., description="Instructions to fill the form")
|
|
124
129
|
template_id: Optional[str] = Field(default=None, description="Template ID to use for filling. When provided, uses the template's pre-defined form fields and empty PDF. Only works for PDF documents. Mutually exclusive with document.")
|
|
130
|
+
config: EditConfig = Field(default_factory=EditConfig, description="Configuration for the edit request")
|
|
125
131
|
|
|
126
132
|
class EditResponse(BaseModel):
|
|
127
133
|
"""Response from the fill_form endpoint.
|
|
@@ -5,7 +5,7 @@ from pydantic import BaseModel, Field
|
|
|
5
5
|
import datetime
|
|
6
6
|
|
|
7
7
|
from ..mime import BaseMIMEData, MIMEData
|
|
8
|
-
from ..documents.edit import FormField
|
|
8
|
+
from ..documents.edit import FormField, EditConfig
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
class EditTemplate(BaseModel):
|
|
@@ -48,3 +48,4 @@ class FillTemplateRequest(BaseModel):
|
|
|
48
48
|
model: str = Field(default="retab-small", description="LLM model to use for inference")
|
|
49
49
|
instructions: str = Field(..., description="Instructions to fill the form")
|
|
50
50
|
template_id: str = Field(..., description="Template ID to use for filling. When provided, uses the template's pre-defined form fields and empty PDF. Only works for PDF documents. Mutually exclusive with document.")
|
|
51
|
+
config: EditConfig = Field(default_factory=EditConfig, description="Configuration for the fill request")
|
|
@@ -18,6 +18,8 @@ retab/resources/documents/__init__.py
|
|
|
18
18
|
retab/resources/documents/client.py
|
|
19
19
|
retab/resources/edit/__init__.py
|
|
20
20
|
retab/resources/edit/client.py
|
|
21
|
+
retab/resources/edit/agent/__init__.py
|
|
22
|
+
retab/resources/edit/agent/client.py
|
|
21
23
|
retab/resources/edit/templates/__init__.py
|
|
22
24
|
retab/resources/edit/templates/client.py
|
|
23
25
|
retab/resources/extractions/__init__.py
|
|
@@ -26,6 +28,8 @@ retab/resources/projects/__init__.py
|
|
|
26
28
|
retab/resources/projects/client.py
|
|
27
29
|
retab/resources/workflows/__init__.py
|
|
28
30
|
retab/resources/workflows/client.py
|
|
31
|
+
retab/resources/workflows/runs/__init__.py
|
|
32
|
+
retab/resources/workflows/runs/client.py
|
|
29
33
|
retab/types/__init__.py
|
|
30
34
|
retab/types/chat.py
|
|
31
35
|
retab/types/inference_settings.py
|
|
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
|
|
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
|
|
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
|