retab 0.0.41__py3-none-any.whl → 0.0.43__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.
Files changed (60) hide show
  1. retab/__init__.py +2 -1
  2. retab/client.py +21 -50
  3. retab/resources/consensus/client.py +1 -1
  4. retab/resources/consensus/completions_stream.py +2 -2
  5. retab/resources/consensus/responses.py +1 -1
  6. retab/resources/documents/client.py +103 -76
  7. retab/resources/documents/extractions.py +55 -46
  8. retab/resources/evaluations/client.py +32 -19
  9. retab/resources/evaluations/documents.py +12 -11
  10. retab/resources/evaluations/iterations.py +48 -30
  11. retab/resources/jsonlUtils.py +3 -4
  12. retab/resources/processors/automations/endpoints.py +57 -43
  13. retab/resources/processors/automations/links.py +54 -45
  14. retab/resources/processors/automations/logs.py +2 -2
  15. retab/resources/processors/automations/mailboxes.py +116 -90
  16. retab/resources/processors/automations/outlook.py +126 -86
  17. retab/resources/processors/automations/tests.py +7 -1
  18. retab/resources/processors/client.py +37 -32
  19. retab/resources/usage.py +2 -0
  20. retab/types/ai_models.py +1 -1
  21. retab/types/automations/mailboxes.py +1 -1
  22. retab/types/deprecated_evals.py +195 -0
  23. retab/types/documents/extractions.py +2 -2
  24. retab/types/documents/parse.py +3 -1
  25. retab/types/evaluations/__init__.py +5 -2
  26. retab/types/evaluations/iterations.py +9 -43
  27. retab/types/evaluations/model.py +20 -22
  28. retab/types/extractions.py +35 -9
  29. retab/types/logs.py +5 -6
  30. retab/types/mime.py +1 -10
  31. retab/types/schemas/enhance.py +22 -5
  32. retab/types/schemas/evaluate.py +1 -1
  33. retab/types/schemas/object.py +26 -0
  34. retab/types/standards.py +2 -2
  35. retab/utils/__init__.py +3 -0
  36. retab/utils/ai_models.py +127 -12
  37. retab/utils/hashing.py +24 -0
  38. retab/utils/json_schema.py +1 -26
  39. retab/utils/mime.py +0 -17
  40. retab-0.0.43.dist-info/METADATA +117 -0
  41. {retab-0.0.41.dist-info → retab-0.0.43.dist-info}/RECORD +43 -57
  42. retab/_utils/__init__.py +0 -0
  43. retab/_utils/_model_cards/anthropic.yaml +0 -59
  44. retab/_utils/_model_cards/auto.yaml +0 -43
  45. retab/_utils/_model_cards/gemini.yaml +0 -117
  46. retab/_utils/_model_cards/openai.yaml +0 -301
  47. retab/_utils/_model_cards/xai.yaml +0 -28
  48. retab/_utils/ai_models.py +0 -138
  49. retab/_utils/benchmarking.py +0 -484
  50. retab/_utils/chat.py +0 -327
  51. retab/_utils/display.py +0 -440
  52. retab/_utils/json_schema.py +0 -2156
  53. retab/_utils/mime.py +0 -165
  54. retab/_utils/responses.py +0 -169
  55. retab/_utils/stream_context_managers.py +0 -52
  56. retab/_utils/usage/__init__.py +0 -0
  57. retab/_utils/usage/usage.py +0 -301
  58. retab-0.0.41.dist-info/METADATA +0 -418
  59. {retab-0.0.41.dist-info → retab-0.0.43.dist-info}/WHEEL +0 -0
  60. {retab-0.0.41.dist-info → retab-0.0.43.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
- from typing import Literal, Optional
1
+ from typing import Any, Literal, Optional
2
2
 
3
- from pydantic_core import PydanticUndefined
3
+ from ....types.standards import FieldUnset
4
4
 
5
5
  from ...._resource import AsyncAPIResource, SyncAPIResource
6
6
  from ....utils.ai_models import assert_valid_model_extraction
@@ -15,22 +15,27 @@ class EndpointsMixin:
15
15
  name: str,
16
16
  webhook_url: str,
17
17
  model: str = "gpt-4o-mini",
18
- webhook_headers: dict[str, str] = PydanticUndefined, # type: ignore[assignment]
19
- need_validation: bool = PydanticUndefined, # type: ignore[assignment]
18
+ webhook_headers: dict[str, str] = FieldUnset,
19
+ need_validation: bool = FieldUnset,
20
20
  ) -> PreparedRequest:
21
21
  assert_valid_model_extraction(model)
22
22
 
23
- request = Endpoint(
24
- processor_id=processor_id,
25
- name=name,
26
- webhook_url=webhook_url,
27
- webhook_headers=webhook_headers,
28
- need_validation=need_validation,
29
- )
30
- return PreparedRequest(method="POST", url="/v1/processors/automations/endpoints", data=request.model_dump(mode="json"))
23
+ endpoint_dict: dict[str, Any] = {
24
+ 'processor_id': processor_id,
25
+ 'name': name,
26
+ 'webhook_url': webhook_url,
27
+ }
28
+ if webhook_headers is not FieldUnset:
29
+ endpoint_dict['webhook_headers'] = webhook_headers
30
+ if need_validation is not FieldUnset:
31
+ endpoint_dict['need_validation'] = need_validation
32
+
33
+ request = Endpoint(**endpoint_dict)
34
+ return PreparedRequest(method="POST", url="/v1/processors/automations/endpoints", data=request.model_dump(mode="json", exclude_unset=True))
31
35
 
32
36
  def prepare_list(
33
37
  self,
38
+ processor_id: str,
34
39
  before: Optional[str] = None,
35
40
  after: Optional[str] = None,
36
41
  limit: Optional[int] = 10,
@@ -40,6 +45,7 @@ class EndpointsMixin:
40
45
  webhook_url: Optional[str] = None,
41
46
  ) -> PreparedRequest:
42
47
  params = {
48
+ "processor_id": processor_id,
43
49
  "before": before,
44
50
  "after": after,
45
51
  "limit": limit,
@@ -66,20 +72,26 @@ class EndpointsMixin:
66
72
  def prepare_update(
67
73
  self,
68
74
  endpoint_id: str,
69
- name: str = PydanticUndefined, # type: ignore[assignment]
70
- default_language: str = PydanticUndefined, # type: ignore[assignment]
71
- webhook_url: str = PydanticUndefined, # type: ignore[assignment]
72
- webhook_headers: dict[str, str] = PydanticUndefined, # type: ignore[assignment]
73
- need_validation: bool = PydanticUndefined, # type: ignore[assignment]
75
+ name: str = FieldUnset,
76
+ default_language: str = FieldUnset,
77
+ webhook_url: str = FieldUnset,
78
+ webhook_headers: dict[str, str] = FieldUnset,
79
+ need_validation: bool = FieldUnset,
74
80
  ) -> PreparedRequest:
75
- request = UpdateEndpointRequest(
76
- name=name,
77
- default_language=default_language,
78
- webhook_url=webhook_url,
79
- webhook_headers=webhook_headers,
80
- need_validation=need_validation,
81
- )
82
- return PreparedRequest(method="PUT", url=f"/v1/processors/automations/endpoints/{endpoint_id}", data=request.model_dump(mode="json"))
81
+ update_dict: dict[str, Any] = {}
82
+ if name is not FieldUnset:
83
+ update_dict['name'] = name
84
+ if default_language is not FieldUnset:
85
+ update_dict['default_language'] = default_language
86
+ if webhook_url is not FieldUnset:
87
+ update_dict['webhook_url'] = webhook_url
88
+ if webhook_headers is not FieldUnset:
89
+ update_dict['webhook_headers'] = webhook_headers
90
+ if need_validation is not FieldUnset:
91
+ update_dict['need_validation'] = need_validation
92
+
93
+ request = UpdateEndpointRequest(**update_dict)
94
+ return PreparedRequest(method="PUT", url=f"/v1/processors/automations/endpoints/{endpoint_id}", data=request.model_dump(mode="json", exclude_unset=True))
83
95
 
84
96
  def prepare_delete(self, endpoint_id: str) -> PreparedRequest:
85
97
  return PreparedRequest(method="DELETE", url=f"/v1/processors/automations/endpoints/{endpoint_id}")
@@ -93,8 +105,8 @@ class Endpoints(SyncAPIResource, EndpointsMixin):
93
105
  processor_id: str,
94
106
  name: str,
95
107
  webhook_url: str,
96
- webhook_headers: dict[str, str] = PydanticUndefined, # type: ignore[assignment]
97
- need_validation: bool = PydanticUndefined, # type: ignore[assignment]
108
+ webhook_headers: dict[str, str] = FieldUnset,
109
+ need_validation: bool = FieldUnset,
98
110
  ) -> Endpoint:
99
111
  """Create a new endpoint configuration.
100
112
 
@@ -120,11 +132,12 @@ class Endpoints(SyncAPIResource, EndpointsMixin):
120
132
  need_validation=need_validation,
121
133
  )
122
134
  response = self._client._prepared_request(request)
123
- print(f"Endpoint Created. Url: https://www.retab.dev/dashboard/processors/automations/{response['id']}")
135
+ print(f"Endpoint Created. Url: https://www.retab.com/dashboard/processors/automations/{response['id']}")
124
136
  return Endpoint.model_validate(response)
125
137
 
126
138
  def list(
127
139
  self,
140
+ processor_id: str,
128
141
  before: Optional[str] = None,
129
142
  after: Optional[str] = None,
130
143
  limit: Optional[int] = 10,
@@ -145,7 +158,7 @@ class Endpoints(SyncAPIResource, EndpointsMixin):
145
158
  Returns:
146
159
  ListEndpoints: Paginated list of endpoint configurations with metadata
147
160
  """
148
- request = self.prepare_list(before, after, limit, order, name, webhook_url)
161
+ request = self.prepare_list(processor_id, before, after, limit, order, name, webhook_url)
149
162
  response = self._client._prepared_request(request)
150
163
  return ListEndpoints.model_validate(response)
151
164
 
@@ -165,11 +178,11 @@ class Endpoints(SyncAPIResource, EndpointsMixin):
165
178
  def update(
166
179
  self,
167
180
  endpoint_id: str,
168
- name: str = PydanticUndefined, # type: ignore[assignment]
169
- default_language: str = PydanticUndefined, # type: ignore[assignment]
170
- webhook_url: str = PydanticUndefined, # type: ignore[assignment]
171
- webhook_headers: dict[str, str] = PydanticUndefined, # type: ignore[assignment]
172
- need_validation: bool = PydanticUndefined, # type: ignore[assignment]
181
+ name: str = FieldUnset,
182
+ default_language: str = FieldUnset,
183
+ webhook_url: str = FieldUnset,
184
+ webhook_headers: dict[str, str] = FieldUnset,
185
+ need_validation: bool = FieldUnset,
173
186
  ) -> Endpoint:
174
187
  """Update an endpoint configuration.
175
188
 
@@ -218,8 +231,8 @@ class AsyncEndpoints(AsyncAPIResource, EndpointsMixin):
218
231
  processor_id: str,
219
232
  name: str,
220
233
  webhook_url: str,
221
- webhook_headers: dict[str, str] = PydanticUndefined, # type: ignore[assignment]
222
- need_validation: bool = PydanticUndefined, # type: ignore[assignment]
234
+ webhook_headers: dict[str, str] = FieldUnset,
235
+ need_validation: bool = FieldUnset,
223
236
  ) -> Endpoint:
224
237
  request = self.prepare_create(
225
238
  processor_id=processor_id,
@@ -229,12 +242,13 @@ class AsyncEndpoints(AsyncAPIResource, EndpointsMixin):
229
242
  need_validation=need_validation,
230
243
  )
231
244
  response = await self._client._prepared_request(request)
232
- print(f"Endpoint Created. Url: https://www.retab.dev/dashboard/processors/automations/{response['id']}")
245
+ print(f"Endpoint Created. Url: https://www.retab.com/dashboard/processors/automations/{response['id']}")
233
246
 
234
247
  return Endpoint.model_validate(response)
235
248
 
236
249
  async def list(
237
250
  self,
251
+ processor_id: str,
238
252
  before: Optional[str] = None,
239
253
  after: Optional[str] = None,
240
254
  limit: Optional[int] = 10,
@@ -242,7 +256,7 @@ class AsyncEndpoints(AsyncAPIResource, EndpointsMixin):
242
256
  name: Optional[str] = None,
243
257
  webhook_url: Optional[str] = None,
244
258
  ) -> ListEndpoints:
245
- request = self.prepare_list(before, after, limit, order, name, webhook_url)
259
+ request = self.prepare_list(processor_id, before, after, limit, order, name, webhook_url)
246
260
  response = await self._client._prepared_request(request)
247
261
  return ListEndpoints.model_validate(response)
248
262
 
@@ -254,11 +268,11 @@ class AsyncEndpoints(AsyncAPIResource, EndpointsMixin):
254
268
  async def update(
255
269
  self,
256
270
  endpoint_id: str,
257
- name: str = PydanticUndefined, # type: ignore[assignment]
258
- default_language: str = PydanticUndefined, # type: ignore[assignment]
259
- webhook_url: str = PydanticUndefined, # type: ignore[assignment]
260
- webhook_headers: dict[str, str] = PydanticUndefined, # type: ignore[assignment]
261
- need_validation: bool = PydanticUndefined, # type: ignore[assignment]
271
+ name: str = FieldUnset,
272
+ default_language: str = FieldUnset,
273
+ webhook_url: str = FieldUnset,
274
+ webhook_headers: dict[str, str] = FieldUnset,
275
+ need_validation: bool = FieldUnset,
262
276
  ) -> Endpoint:
263
277
  request = self.prepare_update(
264
278
  endpoint_id=endpoint_id,
@@ -1,10 +1,8 @@
1
1
  from typing import Any, Literal, Optional
2
2
 
3
- from pydantic_core import PydanticUndefined
4
-
5
3
  from ...._resource import AsyncAPIResource, SyncAPIResource
6
4
  from ....types.automations.links import Link, ListLinks, UpdateLinkRequest
7
- from ....types.standards import PreparedRequest
5
+ from ....types.standards import PreparedRequest, FieldUnset
8
6
 
9
7
 
10
8
  class LinksMixin:
@@ -15,19 +13,24 @@ class LinksMixin:
15
13
  processor_id: str,
16
14
  name: str,
17
15
  webhook_url: str,
18
- webhook_headers: dict[str, str] = PydanticUndefined, # type: ignore[assignment]
19
- need_validation: bool = PydanticUndefined, # type: ignore[assignment]
20
- password: str | None = PydanticUndefined, # type: ignore[assignment]
16
+ webhook_headers: dict[str, str] = FieldUnset,
17
+ need_validation: bool = FieldUnset,
18
+ password: str | None = FieldUnset,
21
19
  ) -> PreparedRequest:
22
- request = Link(
23
- processor_id=processor_id,
24
- name=name,
25
- webhook_url=webhook_url,
26
- webhook_headers=webhook_headers,
27
- need_validation=need_validation,
28
- password=password,
29
- )
30
- return PreparedRequest(method="POST", url=self.links_base_url, data=request.model_dump(mode="json"))
20
+ link_dict: dict[str, Any] = {
21
+ 'processor_id': processor_id,
22
+ 'name': name,
23
+ 'webhook_url': webhook_url,
24
+ }
25
+ if webhook_headers is not FieldUnset:
26
+ link_dict['webhook_headers'] = webhook_headers
27
+ if need_validation is not FieldUnset:
28
+ link_dict['need_validation'] = need_validation
29
+ if password is not FieldUnset:
30
+ link_dict['password'] = password
31
+
32
+ request = Link(**link_dict)
33
+ return PreparedRequest(method="POST", url=self.links_base_url, data=request.model_dump(mode="json", exclude_unset=True))
31
34
 
32
35
  def prepare_list(
33
36
  self,
@@ -66,19 +69,25 @@ class LinksMixin:
66
69
  def prepare_update(
67
70
  self,
68
71
  link_id: str,
69
- name: str = PydanticUndefined, # type: ignore[assignment]
70
- webhook_url: str = PydanticUndefined, # type: ignore[assignment]
71
- webhook_headers: dict[str, str] = PydanticUndefined, # type: ignore[assignment]
72
- need_validation: bool = PydanticUndefined, # type: ignore[assignment]
73
- password: str | None = PydanticUndefined, # type: ignore[assignment]
72
+ name: str = FieldUnset,
73
+ webhook_url: str = FieldUnset,
74
+ webhook_headers: dict[str, str] = FieldUnset,
75
+ need_validation: bool = FieldUnset,
76
+ password: str | None = FieldUnset,
74
77
  ) -> PreparedRequest:
75
- request = UpdateLinkRequest(
76
- name=name,
77
- webhook_url=webhook_url,
78
- webhook_headers=webhook_headers,
79
- need_validation=need_validation,
80
- password=password,
81
- )
78
+ update_dict: dict[str, Any] = {}
79
+ if name is not FieldUnset:
80
+ update_dict['name'] = name
81
+ if webhook_url is not FieldUnset:
82
+ update_dict['webhook_url'] = webhook_url
83
+ if webhook_headers is not FieldUnset:
84
+ update_dict['webhook_headers'] = webhook_headers
85
+ if need_validation is not FieldUnset:
86
+ update_dict['need_validation'] = need_validation
87
+ if password is not FieldUnset:
88
+ update_dict['password'] = password
89
+
90
+ request = UpdateLinkRequest(**update_dict)
82
91
  return PreparedRequest(method="PUT", url=f"{self.links_base_url}/{link_id}", data=request.model_dump(mode="json", exclude_unset=True, exclude_defaults=True))
83
92
 
84
93
  def prepare_delete(self, link_id: str) -> PreparedRequest:
@@ -96,9 +105,9 @@ class Links(SyncAPIResource, LinksMixin):
96
105
  processor_id: str,
97
106
  name: str,
98
107
  webhook_url: str,
99
- webhook_headers: dict[str, str] = PydanticUndefined, # type: ignore[assignment]
100
- need_validation: bool = PydanticUndefined, # type: ignore[assignment]
101
- password: str | None = PydanticUndefined, # type: ignore[assignment]
108
+ webhook_headers: dict[str, str] = FieldUnset,
109
+ need_validation: bool = FieldUnset,
110
+ password: str | None = FieldUnset,
102
111
  ) -> Link:
103
112
  """Create a new extraction link configuration.
104
113
 
@@ -128,7 +137,7 @@ class Links(SyncAPIResource, LinksMixin):
128
137
  )
129
138
  response = self._client._prepared_request(request)
130
139
 
131
- print(f"Link Created. Url: https://www.retab.dev/dashboard/processors/automations/{response['id']}")
140
+ print(f"Link Created. Url: https://www.retab.com/dashboard/processors/automations/{response['id']}")
132
141
  return Link.model_validate(response)
133
142
 
134
143
  def list(
@@ -174,11 +183,11 @@ class Links(SyncAPIResource, LinksMixin):
174
183
  def update(
175
184
  self,
176
185
  link_id: str,
177
- name: str = PydanticUndefined, # type: ignore[assignment]
178
- webhook_url: str = PydanticUndefined, # type: ignore[assignment]
179
- webhook_headers: dict[str, str] = PydanticUndefined, # type: ignore[assignment]
180
- password: str | None = PydanticUndefined, # type: ignore[assignment]
181
- need_validation: bool = PydanticUndefined, # type: ignore[assignment]
186
+ name: str = FieldUnset,
187
+ webhook_url: str = FieldUnset,
188
+ webhook_headers: dict[str, str] = FieldUnset,
189
+ password: str | None = FieldUnset,
190
+ need_validation: bool = FieldUnset,
182
191
  ) -> Link:
183
192
  """Update an extraction link configuration.
184
193
 
@@ -235,9 +244,9 @@ class AsyncLinks(AsyncAPIResource, LinksMixin):
235
244
  processor_id: str,
236
245
  name: str,
237
246
  webhook_url: str,
238
- webhook_headers: dict[str, str] = PydanticUndefined, # type: ignore[assignment]
239
- need_validation: bool = PydanticUndefined, # type: ignore[assignment]
240
- password: str | None = PydanticUndefined, # type: ignore[assignment]
247
+ webhook_headers: dict[str, str] = FieldUnset,
248
+ need_validation: bool = FieldUnset,
249
+ password: str | None = FieldUnset,
241
250
  ) -> Link:
242
251
  request = self.prepare_create(
243
252
  processor_id=processor_id,
@@ -248,7 +257,7 @@ class AsyncLinks(AsyncAPIResource, LinksMixin):
248
257
  password=password,
249
258
  )
250
259
  response = await self._client._prepared_request(request)
251
- print(f"Link Created. Url: https://www.retab.dev/dashboard/processors/automations/{response['id']}")
260
+ print(f"Link Created. Url: https://www.retab.com/dashboard/processors/automations/{response['id']}")
252
261
  return Link.model_validate(response)
253
262
 
254
263
  async def list(
@@ -272,11 +281,11 @@ class AsyncLinks(AsyncAPIResource, LinksMixin):
272
281
  async def update(
273
282
  self,
274
283
  link_id: str,
275
- name: str = PydanticUndefined, # type: ignore[assignment]
276
- webhook_url: str = PydanticUndefined, # type: ignore[assignment]
277
- webhook_headers: dict[str, str] = PydanticUndefined, # type: ignore[assignment]
278
- password: str | None = PydanticUndefined, # type: ignore[assignment]
279
- need_validation: bool = PydanticUndefined, # type: ignore[assignment]
284
+ name: str = FieldUnset,
285
+ webhook_url: str = FieldUnset,
286
+ webhook_headers: dict[str, str] = FieldUnset,
287
+ password: str | None = FieldUnset,
288
+ need_validation: bool = FieldUnset,
280
289
  ) -> Link:
281
290
  request = self.prepare_update(
282
291
  link_id=link_id,
@@ -147,7 +147,7 @@ class Logs(SyncAPIResource, LogsMixin):
147
147
  request = self.prepare_rerun(processor_id, log_id)
148
148
  response = self._client._prepared_request(request)
149
149
 
150
- print(f"Webhook call run successfully. Log available at https://www.retab.dev/dashboard/processors/{processor_id}/logs/{log_id}")
150
+ print(f"Webhook call run successfully. Log available at https://www.retab.com/dashboard/processors/{processor_id}/logs/{log_id}")
151
151
 
152
152
  return ExternalRequestLog.model_validate(response)
153
153
 
@@ -217,6 +217,6 @@ class AsyncLogs(AsyncAPIResource, LogsMixin):
217
217
  request = self.prepare_rerun(processor_id, log_id)
218
218
  response = await self._client._prepared_request(request)
219
219
 
220
- print(f"Webhook call run successfully. Log available at https://www.retab.dev/dashboard/processors/{processor_id}/logs/{log_id}")
220
+ print(f"Webhook call run successfully. Log available at https://www.retab.com/dashboard/processors/{processor_id}/logs/{log_id}")
221
221
 
222
222
  return ExternalRequestLog.model_validate(response)