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
@@ -3,7 +3,7 @@ from pathlib import Path
3
3
  from typing import Any, List, Literal, Optional
4
4
 
5
5
  from pydantic import EmailStr, HttpUrl
6
- from pydantic_core import PydanticUndefined
6
+ from ....types.standards import FieldUnset
7
7
 
8
8
  from ...._resource import AsyncAPIResource, SyncAPIResource
9
9
  from ....utils.mime import prepare_mime_document
@@ -21,28 +21,36 @@ class MailBoxesMixin:
21
21
  name: str,
22
22
  processor_id: str,
23
23
  webhook_url: str,
24
- authorized_domains: list[str] = PydanticUndefined, # type: ignore[assignment]
25
- authorized_emails: list[EmailStr] = PydanticUndefined, # type: ignore[assignment]
26
- webhook_headers: dict[str, str] = PydanticUndefined, # type: ignore[assignment]
27
- default_language: str = PydanticUndefined, # type: ignore[assignment]
28
- need_validation: bool = PydanticUndefined, # type: ignore[assignment]
24
+ authorized_domains: list[str] = FieldUnset,
25
+ authorized_emails: list[EmailStr] = FieldUnset,
26
+ webhook_headers: dict[str, str] = FieldUnset,
27
+ default_language: str = FieldUnset,
28
+ need_validation: bool = FieldUnset,
29
29
  ) -> PreparedRequest:
30
30
  """Create a new email automation configuration."""
31
- mailbox = Mailbox(
32
- name=name,
33
- processor_id=processor_id,
34
- default_language=default_language,
35
- webhook_url=webhook_url,
36
- webhook_headers=webhook_headers,
37
- need_validation=need_validation,
38
- email=email,
39
- authorized_domains=authorized_domains,
40
- authorized_emails=authorized_emails,
41
- )
42
- return PreparedRequest(method="POST", url=self.mailboxes_base_url, data=mailbox.model_dump(mode="json"))
31
+ mailbox_dict: dict[str, Any] = {
32
+ 'name': name,
33
+ 'processor_id': processor_id,
34
+ 'webhook_url': webhook_url,
35
+ 'email': email,
36
+ }
37
+ if default_language is not FieldUnset:
38
+ mailbox_dict['default_language'] = default_language
39
+ if webhook_headers is not FieldUnset:
40
+ mailbox_dict['webhook_headers'] = webhook_headers
41
+ if need_validation is not FieldUnset:
42
+ mailbox_dict['need_validation'] = need_validation
43
+ if authorized_domains is not FieldUnset:
44
+ mailbox_dict['authorized_domains'] = authorized_domains
45
+ if authorized_emails is not FieldUnset:
46
+ mailbox_dict['authorized_emails'] = authorized_emails
47
+
48
+ mailbox = Mailbox(**mailbox_dict)
49
+ return PreparedRequest(method="POST", url=self.mailboxes_base_url, data=mailbox.model_dump(mode="json", exclude_unset=True))
43
50
 
44
51
  def prepare_list(
45
52
  self,
53
+ processor_id: str,
46
54
  before: str | None = None,
47
55
  after: str | None = None,
48
56
  limit: int = 10,
@@ -52,6 +60,7 @@ class MailBoxesMixin:
52
60
  webhook_url: Optional[str] = None,
53
61
  ) -> PreparedRequest:
54
62
  params = {
63
+ "processor_id": processor_id,
55
64
  "before": before,
56
65
  "after": after,
57
66
  "limit": limit,
@@ -65,36 +74,41 @@ class MailBoxesMixin:
65
74
 
66
75
  return PreparedRequest(method="GET", url=self.mailboxes_base_url, params=params)
67
76
 
68
- def prepare_get(self, email: str) -> PreparedRequest:
69
- return PreparedRequest(method="GET", url=f"{self.mailboxes_base_url}/{email}")
70
-
71
- def prepare_get_from_id(self, mailbox_id: str) -> PreparedRequest:
72
- return PreparedRequest(method="GET", url=f"{self.mailboxes_base_url}/from_id/{mailbox_id}")
77
+ def prepare_get(self, mailbox_id: str) -> PreparedRequest:
78
+ return PreparedRequest(method="GET", url=f"{self.mailboxes_base_url}/{mailbox_id}")
73
79
 
74
80
  def prepare_update(
75
81
  self,
76
- email: str,
77
- name: str = PydanticUndefined, # type: ignore[assignment]
78
- default_language: str = PydanticUndefined, # type: ignore[assignment]
79
- webhook_url: str = PydanticUndefined, # type: ignore[assignment]
80
- webhook_headers: dict[str, str] = PydanticUndefined, # type: ignore[assignment]
81
- need_validation: bool = PydanticUndefined, # type: ignore[assignment]
82
- authorized_domains: list[str] = PydanticUndefined, # type: ignore[assignment]
83
- authorized_emails: list[str] = PydanticUndefined, # type: ignore[assignment]
82
+ mailbox_id: str,
83
+ name: str = FieldUnset,
84
+ default_language: str = FieldUnset,
85
+ webhook_url: str = FieldUnset,
86
+ webhook_headers: dict[str, str] = FieldUnset,
87
+ need_validation: bool = FieldUnset,
88
+ authorized_domains: list[str] = FieldUnset,
89
+ authorized_emails: list[str] = FieldUnset,
84
90
  ) -> PreparedRequest:
85
- update_mailbox_request = UpdateMailboxRequest(
86
- name=name,
87
- default_language=default_language,
88
- webhook_url=webhook_url,
89
- webhook_headers=webhook_headers,
90
- need_validation=need_validation,
91
- authorized_domains=authorized_domains,
92
- authorized_emails=authorized_emails,
93
- )
94
- return PreparedRequest(method="PUT", url=f"/v1/processors/automations/mailboxes/{email}", data=update_mailbox_request.model_dump(mode="json"))
95
-
96
- def prepare_delete(self, email: str) -> PreparedRequest:
97
- return PreparedRequest(method="DELETE", url=f"/v1/processors/automations/mailboxes/{email}", raise_for_status=True)
91
+ update_dict: dict[str, Any] = {}
92
+ if name is not FieldUnset:
93
+ update_dict['name'] = name
94
+ if default_language is not FieldUnset:
95
+ update_dict['default_language'] = default_language
96
+ if webhook_url is not FieldUnset:
97
+ update_dict['webhook_url'] = webhook_url
98
+ if webhook_headers is not FieldUnset:
99
+ update_dict['webhook_headers'] = webhook_headers
100
+ if need_validation is not FieldUnset:
101
+ update_dict['need_validation'] = need_validation
102
+ if authorized_domains is not FieldUnset:
103
+ update_dict['authorized_domains'] = authorized_domains
104
+ if authorized_emails is not FieldUnset:
105
+ update_dict['authorized_emails'] = authorized_emails
106
+
107
+ update_mailbox_request = UpdateMailboxRequest(**update_dict)
108
+ return PreparedRequest(method="PUT", url=f"/v1/processors/automations/mailboxes/{mailbox_id}", data=update_mailbox_request.model_dump(mode="json", exclude_unset=True))
109
+
110
+ def prepare_delete(self, mailbox_id: str) -> PreparedRequest:
111
+ return PreparedRequest(method="DELETE", url=f"/v1/processors/automations/mailboxes/{mailbox_id}", raise_for_status=True)
98
112
 
99
113
 
100
114
  class Mailboxes(SyncAPIResource, MailBoxesMixin):
@@ -110,11 +124,11 @@ class Mailboxes(SyncAPIResource, MailBoxesMixin):
110
124
  name: str,
111
125
  webhook_url: str,
112
126
  processor_id: str,
113
- authorized_domains: list[str] = PydanticUndefined, # type: ignore[assignment]
114
- authorized_emails: list[EmailStr] = PydanticUndefined, # type: ignore[assignment]
115
- webhook_headers: dict[str, str] = PydanticUndefined, # type: ignore[assignment]
116
- default_language: str = PydanticUndefined, # type: ignore[assignment]
117
- need_validation: bool = PydanticUndefined, # type: ignore[assignment]
127
+ authorized_domains: list[str] = FieldUnset,
128
+ authorized_emails: list[EmailStr] = FieldUnset,
129
+ webhook_headers: dict[str, str] = FieldUnset,
130
+ default_language: str = FieldUnset,
131
+ need_validation: bool = FieldUnset,
118
132
  ) -> Mailbox:
119
133
  """Create a new email automation configuration.
120
134
 
@@ -144,12 +158,13 @@ class Mailboxes(SyncAPIResource, MailBoxesMixin):
144
158
  )
145
159
  response = self._client._prepared_request(request)
146
160
 
147
- print(f"Mailbox {response['email']} created. Url: https://www.retab.dev/dashboard/processors/automations/{response['id']}")
161
+ print(f"Mailbox {response['email']} created. Url: https://www.retab.com/dashboard/processors/automations/{response['id']}")
148
162
 
149
163
  return Mailbox.model_validate(response)
150
164
 
151
165
  def list(
152
166
  self,
167
+ processor_id: str,
153
168
  before: str | None = None,
154
169
  after: str | None = None,
155
170
  limit: int = 10,
@@ -174,6 +189,7 @@ class Mailboxes(SyncAPIResource, MailBoxesMixin):
174
189
  ListMailboxes: List of mailbox configurations
175
190
  """
176
191
  request = self.prepare_list(
192
+ processor_id=processor_id,
177
193
  before=before,
178
194
  after=after,
179
195
  limit=limit,
@@ -185,29 +201,29 @@ class Mailboxes(SyncAPIResource, MailBoxesMixin):
185
201
  response = self._client._prepared_request(request)
186
202
  return ListMailboxes.model_validate(response)
187
203
 
188
- def get(self, email: str) -> Mailbox:
204
+ def get(self, mailbox_id: str) -> Mailbox:
189
205
  """Get a specific email automation configuration.
190
206
 
191
207
  Args:
192
- email: Email address of the mailbox
208
+ mailbox_id: ID of the mailbox
193
209
 
194
210
  Returns:
195
211
  Mailbox: The mailbox configuration
196
212
  """
197
- request = self.prepare_get(email)
213
+ request = self.prepare_get(mailbox_id)
198
214
  response = self._client._prepared_request(request)
199
215
  return Mailbox.model_validate(response)
200
216
 
201
217
  def update(
202
218
  self,
203
- email: str,
204
- name: str = PydanticUndefined, # type: ignore[assignment]
205
- default_language: str = PydanticUndefined, # type: ignore[assignment]
206
- webhook_url: str = PydanticUndefined, # type: ignore[assignment]
207
- webhook_headers: dict[str, str] = PydanticUndefined, # type: ignore[assignment]
208
- need_validation: bool = PydanticUndefined, # type: ignore[assignment]
209
- authorized_domains: List[str] = PydanticUndefined, # type: ignore[assignment]
210
- authorized_emails: List[str] = PydanticUndefined, # type: ignore[assignment]
219
+ mailbox_id: str,
220
+ name: str = FieldUnset,
221
+ default_language: str = FieldUnset,
222
+ webhook_url: str = FieldUnset,
223
+ webhook_headers: dict[str, str] = FieldUnset,
224
+ need_validation: bool = FieldUnset,
225
+ authorized_domains: List[str] = FieldUnset,
226
+ authorized_emails: List[str] = FieldUnset,
211
227
  ) -> Mailbox:
212
228
  """Update an email automation configuration.
213
229
 
@@ -225,7 +241,7 @@ class Mailboxes(SyncAPIResource, MailBoxesMixin):
225
241
  Mailbox: The updated mailbox configuration
226
242
  """
227
243
  request = self.prepare_update(
228
- email=email,
244
+ mailbox_id=mailbox_id,
229
245
  name=name,
230
246
  default_language=default_language,
231
247
  webhook_url=webhook_url,
@@ -237,13 +253,13 @@ class Mailboxes(SyncAPIResource, MailBoxesMixin):
237
253
  response = self._client._prepared_request(request)
238
254
  return Mailbox.model_validate(response)
239
255
 
240
- def delete(self, email: str) -> None:
256
+ def delete(self, mailbox_id: str) -> None:
241
257
  """Delete an email automation configuration.
242
258
 
243
259
  Args:
244
260
  email: Email address of the mailbox to delete
245
261
  """
246
- request = self.prepare_delete(email)
262
+ request = self.prepare_delete(mailbox_id)
247
263
  self._client._prepared_request(request)
248
264
  return None
249
265
 
@@ -259,11 +275,11 @@ class AsyncMailboxes(AsyncAPIResource, MailBoxesMixin):
259
275
  name: str,
260
276
  webhook_url: str,
261
277
  processor_id: str,
262
- authorized_domains: List[str] = PydanticUndefined, # type: ignore[assignment]
263
- authorized_emails: List[EmailStr] = PydanticUndefined, # type: ignore[assignment]
264
- webhook_headers: dict[str, str] = PydanticUndefined, # type: ignore[assignment]
265
- default_language: str = PydanticUndefined, # type: ignore[assignment]
266
- need_validation: bool = PydanticUndefined, # type: ignore[assignment]
278
+ authorized_domains: List[str] = FieldUnset,
279
+ authorized_emails: List[EmailStr] = FieldUnset,
280
+ webhook_headers: dict[str, str] = FieldUnset,
281
+ default_language: str = FieldUnset,
282
+ need_validation: bool = FieldUnset,
267
283
  ) -> Mailbox:
268
284
  request = self.prepare_create(
269
285
  email=email,
@@ -278,12 +294,13 @@ class AsyncMailboxes(AsyncAPIResource, MailBoxesMixin):
278
294
  )
279
295
  response = await self._client._prepared_request(request)
280
296
 
281
- print(f"Mailbox {response['email']} created. Url: https://www.retab.dev/dashboard/processors/automations/{response['id']}")
297
+ print(f"Mailbox {response['email']} created. Url: https://www.retab.com/dashboard/processors/automations/{response['id']}")
282
298
 
283
299
  return Mailbox.model_validate(response)
284
300
 
285
301
  async def list(
286
302
  self,
303
+ processor_id: str,
287
304
  before: str | None = None,
288
305
  after: str | None = None,
289
306
  limit: int = 10,
@@ -292,28 +309,37 @@ class AsyncMailboxes(AsyncAPIResource, MailBoxesMixin):
292
309
  name: str | None = None,
293
310
  webhook_url: str | None = None,
294
311
  ) -> ListMailboxes:
295
- request = self.prepare_list(before=before, after=after, limit=limit, order=order, email=email, name=name, webhook_url=webhook_url)
312
+ request = self.prepare_list(
313
+ processor_id=processor_id,
314
+ before=before,
315
+ after=after,
316
+ limit=limit,
317
+ order=order,
318
+ email=email,
319
+ name=name,
320
+ webhook_url=webhook_url,
321
+ )
296
322
  response = await self._client._prepared_request(request)
297
323
  return ListMailboxes.model_validate(response)
298
324
 
299
- async def get(self, email: str) -> Mailbox:
300
- request = self.prepare_get(email)
325
+ async def get(self, mailbox_id: str) -> Mailbox:
326
+ request = self.prepare_get(mailbox_id)
301
327
  response = await self._client._prepared_request(request)
302
328
  return Mailbox.model_validate(response)
303
329
 
304
330
  async def update(
305
331
  self,
306
- email: str,
307
- name: str = PydanticUndefined, # type: ignore[assignment]
308
- default_language: str = PydanticUndefined, # type: ignore[assignment]
309
- webhook_url: str = PydanticUndefined, # type: ignore[assignment]
310
- webhook_headers: dict[str, str] = PydanticUndefined, # type: ignore[assignment]
311
- need_validation: bool = PydanticUndefined, # type: ignore[assignment]
312
- authorized_domains: List[str] = PydanticUndefined, # type: ignore[assignment]
313
- authorized_emails: List[str] = PydanticUndefined, # type: ignore[assignment]
332
+ mailbox_id: str,
333
+ name: str = FieldUnset,
334
+ default_language: str = FieldUnset,
335
+ webhook_url: str = FieldUnset,
336
+ webhook_headers: dict[str, str] = FieldUnset,
337
+ need_validation: bool = FieldUnset,
338
+ authorized_domains: List[str] = FieldUnset,
339
+ authorized_emails: List[str] = FieldUnset,
314
340
  ) -> Mailbox:
315
341
  request = self.prepare_update(
316
- email=email,
342
+ mailbox_id=mailbox_id,
317
343
  name=name,
318
344
  default_language=default_language,
319
345
  webhook_url=webhook_url,
@@ -325,8 +351,8 @@ class AsyncMailboxes(AsyncAPIResource, MailBoxesMixin):
325
351
  response = await self._client._prepared_request(request)
326
352
  return Mailbox.model_validate(response)
327
353
 
328
- async def delete(self, email: str) -> None:
329
- request = self.prepare_delete(email)
354
+ async def delete(self, mailbox_id: str) -> None:
355
+ request = self.prepare_delete(mailbox_id)
330
356
  await self._client._prepared_request(request)
331
357
  return None
332
358
 
@@ -334,12 +360,12 @@ class AsyncMailboxes(AsyncAPIResource, MailBoxesMixin):
334
360
  class TestMailboxesMixin:
335
361
  def prepare_forward(
336
362
  self,
337
- email: str,
363
+ mailbox_id: str,
338
364
  document: Path | str | IOBase | HttpUrl | MIMEData,
339
365
  verbose: bool = True,
340
366
  ) -> PreparedRequest:
341
367
  mime_document = prepare_mime_document(document)
342
- return PreparedRequest(method="POST", url=f"/v1/processors/automations/mailboxes/tests/forward/{email}", data={"document": mime_document.model_dump()})
368
+ return PreparedRequest(method="POST", url=f"/v1/processors/automations/mailboxes/tests/forward/{mailbox_id}", data={"document": mime_document.model_dump()})
343
369
 
344
370
  def print_forward_verbose(self, email_data: EmailData) -> None:
345
371
  print("\nTEST EMAIL FORWARDING RESULTS:")
@@ -360,7 +386,7 @@ class TestMailboxesMixin:
360
386
  class TestMailboxes(SyncAPIResource, TestMailboxesMixin):
361
387
  def forward(
362
388
  self,
363
- email: str,
389
+ mailbox_id: str,
364
390
  document: Path | str | IOBase | HttpUrl | MIMEData,
365
391
  verbose: bool = True,
366
392
  ) -> EmailData:
@@ -372,7 +398,7 @@ class TestMailboxes(SyncAPIResource, TestMailboxesMixin):
372
398
  Returns:
373
399
  DocumentExtractResponse: The simulated extraction response
374
400
  """
375
- request = self.prepare_forward(email, document, verbose)
401
+ request = self.prepare_forward(mailbox_id, document, verbose)
376
402
  response = self._client._prepared_request(request)
377
403
 
378
404
  email_data = EmailData.model_validate(response)
@@ -385,11 +411,11 @@ class TestMailboxes(SyncAPIResource, TestMailboxesMixin):
385
411
  class AsyncTestMailboxes(AsyncAPIResource, TestMailboxesMixin):
386
412
  async def forward(
387
413
  self,
388
- email: str,
414
+ mailbox_id: str,
389
415
  document: Path | str | IOBase | HttpUrl | MIMEData,
390
416
  verbose: bool = True,
391
417
  ) -> EmailData:
392
- request = self.prepare_forward(email, document, verbose)
418
+ request = self.prepare_forward(mailbox_id, document, verbose)
393
419
  response = await self._client._prepared_request(request)
394
420
  email_data = EmailData.model_validate(response)
395
421
  if verbose: