retab 0.0.36__py3-none-any.whl → 0.0.37__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 (119) hide show
  1. {uiform → retab}/_utils/ai_models.py +2 -2
  2. {uiform → retab}/_utils/benchmarking.py +15 -16
  3. {uiform → retab}/_utils/chat.py +9 -14
  4. {uiform → retab}/_utils/display.py +0 -3
  5. {uiform → retab}/_utils/json_schema.py +9 -14
  6. {uiform → retab}/_utils/mime.py +11 -14
  7. {uiform → retab}/_utils/responses.py +9 -3
  8. {uiform → retab}/_utils/stream_context_managers.py +1 -1
  9. {uiform → retab}/_utils/usage/usage.py +28 -28
  10. {uiform → retab}/client.py +32 -31
  11. {uiform → retab}/resources/consensus/client.py +17 -36
  12. {uiform → retab}/resources/consensus/completions.py +24 -47
  13. {uiform → retab}/resources/consensus/completions_stream.py +26 -38
  14. {uiform → retab}/resources/consensus/responses.py +31 -80
  15. {uiform → retab}/resources/consensus/responses_stream.py +31 -79
  16. {uiform → retab}/resources/documents/client.py +59 -45
  17. {uiform → retab}/resources/documents/extractions.py +181 -90
  18. {uiform → retab}/resources/evals.py +56 -43
  19. retab/resources/evaluations/__init__.py +3 -0
  20. retab/resources/evaluations/client.py +301 -0
  21. retab/resources/evaluations/documents.py +233 -0
  22. retab/resources/evaluations/iterations.py +452 -0
  23. {uiform → retab}/resources/files.py +2 -2
  24. {uiform → retab}/resources/jsonlUtils.py +220 -216
  25. retab/resources/models.py +73 -0
  26. retab/resources/processors/automations/client.py +244 -0
  27. {uiform → retab}/resources/processors/automations/endpoints.py +77 -118
  28. retab/resources/processors/automations/links.py +294 -0
  29. {uiform → retab}/resources/processors/automations/logs.py +30 -19
  30. {uiform → retab}/resources/processors/automations/mailboxes.py +136 -174
  31. retab/resources/processors/automations/outlook.py +337 -0
  32. {uiform → retab}/resources/processors/automations/tests.py +22 -25
  33. {uiform → retab}/resources/processors/client.py +179 -164
  34. {uiform → retab}/resources/schemas.py +78 -66
  35. {uiform → retab}/resources/secrets/external_api_keys.py +1 -5
  36. retab/resources/secrets/webhook.py +64 -0
  37. {uiform → retab}/resources/usage.py +39 -2
  38. {uiform → retab}/types/ai_models.py +13 -13
  39. {uiform → retab}/types/automations/cron.py +19 -12
  40. {uiform → retab}/types/automations/endpoints.py +7 -4
  41. {uiform → retab}/types/automations/links.py +7 -3
  42. {uiform → retab}/types/automations/mailboxes.py +9 -9
  43. {uiform → retab}/types/automations/outlook.py +15 -11
  44. retab/types/browser_canvas.py +3 -0
  45. {uiform → retab}/types/chat.py +2 -2
  46. {uiform → retab}/types/completions.py +9 -12
  47. retab/types/consensus.py +19 -0
  48. {uiform → retab}/types/db/annotations.py +3 -3
  49. {uiform → retab}/types/db/files.py +8 -6
  50. {uiform → retab}/types/documents/create_messages.py +18 -20
  51. {uiform → retab}/types/documents/extractions.py +69 -24
  52. {uiform → retab}/types/evals.py +5 -5
  53. retab/types/evaluations/__init__.py +31 -0
  54. retab/types/evaluations/documents.py +30 -0
  55. retab/types/evaluations/iterations.py +112 -0
  56. retab/types/evaluations/model.py +73 -0
  57. retab/types/events.py +79 -0
  58. {uiform → retab}/types/extractions.py +33 -10
  59. retab/types/inference_settings.py +15 -0
  60. retab/types/jobs/base.py +54 -0
  61. retab/types/jobs/batch_annotation.py +12 -0
  62. {uiform → retab}/types/jobs/evaluation.py +1 -2
  63. {uiform → retab}/types/logs.py +37 -34
  64. retab/types/metrics.py +32 -0
  65. {uiform → retab}/types/mime.py +22 -20
  66. {uiform → retab}/types/modalities.py +10 -10
  67. retab/types/predictions.py +19 -0
  68. {uiform → retab}/types/schemas/enhance.py +4 -2
  69. {uiform → retab}/types/schemas/evaluate.py +7 -4
  70. {uiform → retab}/types/schemas/generate.py +6 -3
  71. {uiform → retab}/types/schemas/layout.py +1 -1
  72. {uiform → retab}/types/schemas/object.py +13 -14
  73. {uiform → retab}/types/schemas/templates.py +1 -3
  74. {uiform → retab}/types/secrets/external_api_keys.py +0 -1
  75. {uiform → retab}/types/standards.py +18 -1
  76. {retab-0.0.36.dist-info → retab-0.0.37.dist-info}/METADATA +7 -6
  77. retab-0.0.37.dist-info/RECORD +107 -0
  78. retab-0.0.37.dist-info/top_level.txt +1 -0
  79. retab-0.0.36.dist-info/RECORD +0 -96
  80. retab-0.0.36.dist-info/top_level.txt +0 -1
  81. uiform/_utils/benchmarking copy.py +0 -588
  82. uiform/resources/models.py +0 -45
  83. uiform/resources/processors/automations/client.py +0 -78
  84. uiform/resources/processors/automations/links.py +0 -356
  85. uiform/resources/processors/automations/outlook.py +0 -444
  86. uiform/resources/secrets/webhook.py +0 -62
  87. uiform/types/consensus.py +0 -10
  88. uiform/types/events.py +0 -76
  89. uiform/types/jobs/base.py +0 -150
  90. uiform/types/jobs/batch_annotation.py +0 -22
  91. {uiform → retab}/__init__.py +0 -0
  92. {uiform → retab}/_resource.py +0 -0
  93. {uiform → retab}/_utils/__init__.py +0 -0
  94. {uiform → retab}/_utils/usage/__init__.py +0 -0
  95. {uiform → retab}/py.typed +0 -0
  96. {uiform → retab}/resources/__init__.py +0 -0
  97. {uiform → retab}/resources/consensus/__init__.py +0 -0
  98. {uiform → retab}/resources/documents/__init__.py +0 -0
  99. {uiform → retab}/resources/finetuning.py +0 -0
  100. {uiform → retab}/resources/openai_example.py +0 -0
  101. {uiform → retab}/resources/processors/__init__.py +0 -0
  102. {uiform → retab}/resources/processors/automations/__init__.py +0 -0
  103. {uiform → retab}/resources/prompt_optimization.py +0 -0
  104. {uiform → retab}/resources/secrets/__init__.py +0 -0
  105. {uiform → retab}/resources/secrets/client.py +0 -0
  106. {uiform → retab}/types/__init__.py +0 -0
  107. {uiform → retab}/types/automations/__init__.py +0 -0
  108. {uiform → retab}/types/automations/webhooks.py +0 -0
  109. {uiform → retab}/types/db/__init__.py +0 -0
  110. {uiform → retab}/types/documents/__init__.py +0 -0
  111. {uiform → retab}/types/documents/correct_orientation.py +0 -0
  112. {uiform → retab}/types/jobs/__init__.py +0 -0
  113. {uiform → retab}/types/jobs/finetune.py +0 -0
  114. {uiform → retab}/types/jobs/prompt_optimization.py +0 -0
  115. {uiform → retab}/types/jobs/webcrawl.py +0 -0
  116. {uiform → retab}/types/pagination.py +0 -0
  117. {uiform → retab}/types/schemas/__init__.py +0 -0
  118. {uiform → retab}/types/secrets/__init__.py +0 -0
  119. {retab-0.0.36.dist-info → retab-0.0.37.dist-info}/WHEEL +0 -0
@@ -1,78 +0,0 @@
1
- import hashlib
2
- import hmac
3
- import json
4
- from typing import Any
5
-
6
- from ...._resource import AsyncAPIResource, SyncAPIResource
7
- from .endpoints import AsyncEndpoints, Endpoints
8
- from .links import AsyncLinks, Links
9
- from .mailboxes import AsyncMailboxes, Mailboxes
10
- from .outlook import AsyncOutlooks, Outlooks
11
- from .tests import AsyncTests, Tests
12
- from .logs import AsyncLogs, Logs
13
-
14
- class SignatureVerificationError(Exception):
15
- """Raised when webhook signature verification fails."""
16
-
17
- pass
18
-
19
-
20
- class AutomationsMixin:
21
- def _verify_event(self, event_body: bytes, event_signature: str, secret: str) -> Any:
22
- """
23
- Verify the signature of a webhook event.
24
-
25
- Args:
26
- body: The raw request body
27
- signature: The signature header
28
- secret: The secret key used for signing
29
-
30
- Returns:
31
- The parsed event payload
32
-
33
- Raises:
34
- SignatureVerificationError: If the signature verification fails
35
- """
36
- expected_signature = hmac.new(secret.encode(), event_body, hashlib.sha256).hexdigest()
37
-
38
- if not hmac.compare_digest(event_signature, expected_signature):
39
- raise SignatureVerificationError("Invalid signature")
40
-
41
- return json.loads(event_body.decode('utf-8'))
42
-
43
-
44
- class Automations(SyncAPIResource, AutomationsMixin):
45
- """Automations API wrapper"""
46
-
47
- def __init__(self, client: Any) -> None:
48
- super().__init__(client=client)
49
- self.mailboxes = Mailboxes(client=client)
50
- self.links = Links(client=client)
51
- self.outlook = Outlooks(client=client)
52
- self.endpoints = Endpoints(client=client)
53
- self.tests = Tests(client=client)
54
- self.logs = Logs(client=client)
55
- def verify_event(self, event_body: bytes, event_signature: str, secret: str) -> Any:
56
- """
57
- Verify the signature of a webhook event.
58
- """
59
- return self._verify_event(event_body, event_signature, secret)
60
-
61
-
62
- class AsyncAutomations(AsyncAPIResource, AutomationsMixin):
63
- """Async Automations API wrapper"""
64
-
65
- def __init__(self, client: Any) -> None:
66
- super().__init__(client=client)
67
- self.mailboxes = AsyncMailboxes(client=client)
68
- self.links = AsyncLinks(client=client)
69
- self.outlook = AsyncOutlooks(client=client)
70
- self.endpoints = AsyncEndpoints(client=client)
71
- self.tests = AsyncTests(client=client)
72
- self.logs = AsyncLogs(client=client)
73
-
74
- async def verify_event(self, event_body: bytes, event_signature: str, secret: str) -> Any:
75
- """
76
- Verify the signature of a webhook event.
77
- """
78
- return self._verify_event(event_body, event_signature, secret)
@@ -1,356 +0,0 @@
1
- import datetime
2
- import json
3
- from io import IOBase
4
- from pathlib import Path
5
- from typing import Any, Dict, Literal, Optional
6
-
7
- import httpx
8
- from openai.types.chat.chat_completion_reasoning_effort import ChatCompletionReasoningEffort
9
- from PIL.Image import Image
10
- from pydantic import HttpUrl
11
-
12
- from ...._resource import AsyncAPIResource, SyncAPIResource
13
- from ...._utils.ai_models import assert_valid_model_extraction
14
- from ...._utils.mime import prepare_mime_document
15
- from ....types.automations.links import Link, ListLinks, UpdateLinkRequest
16
- from ....types.documents.extractions import UiParsedChatCompletion
17
- from ....types.logs import AutomationLog, ExternalRequestLog, ListLogs
18
- from ....types.mime import BaseMIMEData, MIMEData
19
- from ....types.modalities import Modality
20
- from ....types.standards import PreparedRequest
21
-
22
-
23
- class LinksMixin:
24
- def prepare_create(
25
- self,
26
- name: str,
27
- json_schema: Dict[str, Any],
28
- webhook_url: HttpUrl,
29
- webhook_headers: Optional[Dict[str, str]] = None,
30
- password: str | None = None,
31
- # DocumentExtraction Config
32
- image_resolution_dpi: Optional[int] = None,
33
- browser_canvas: Optional[str] = None,
34
- modality: Modality = "native",
35
- model: str = "gpt-4o-mini",
36
- temperature: float = 0,
37
- reasoning_effort: ChatCompletionReasoningEffort = "medium",
38
- ) -> PreparedRequest:
39
- assert_valid_model_extraction(model)
40
-
41
- data = {
42
- "name": name,
43
- "webhook_url": webhook_url,
44
- "webhook_headers": webhook_headers or {},
45
- "json_schema": json_schema,
46
- "password": password,
47
- "image_resolution_dpi": image_resolution_dpi,
48
- "browser_canvas": browser_canvas,
49
- "modality": modality,
50
- "model": model,
51
- "temperature": temperature,
52
- "reasoning_effort": reasoning_effort,
53
- }
54
-
55
- request = Link.model_validate(data)
56
- return PreparedRequest(method="POST", url="/v1/deployments/links", data=request.model_dump(mode='json'))
57
-
58
- def prepare_list(
59
- self,
60
- before: Optional[str] = None,
61
- after: Optional[str] = None,
62
- limit: Optional[int] = 10,
63
- order: Optional[Literal["asc", "desc"]] = "desc",
64
- # Filtering parameters
65
- link_id: Optional[str] = None,
66
- name: Optional[str] = None,
67
- webhook_url: Optional[str] = None,
68
- schema_id: Optional[str] = None,
69
- schema_data_id: Optional[str] = None,
70
- ) -> PreparedRequest:
71
- params = {
72
- "before": before,
73
- "after": after,
74
- "limit": limit,
75
- "order": order,
76
- "automation_id": link_id,
77
- "name": name,
78
- "webhook_url": webhook_url,
79
- "schema_id": schema_id,
80
- "schema_data_id": schema_data_id,
81
- }
82
- # Remove None values
83
- params = {k: v for k, v in params.items() if v is not None}
84
-
85
- return PreparedRequest(method="GET", url="/v1/deployments", params=params)
86
-
87
- def prepare_get(self, link_id: str) -> PreparedRequest:
88
- """Get a specific extraction link configuration.
89
-
90
- Args:
91
- link_id: ID of the extraction link
92
-
93
- Returns:
94
- Link: The extraction link configuration
95
- """
96
- return PreparedRequest(method="GET", url=f"/v1/deployments/{link_id}")
97
-
98
- def prepare_update(
99
- self,
100
- link_id: str,
101
- name: Optional[str] = None,
102
- webhook_url: Optional[HttpUrl] = None,
103
- webhook_headers: Optional[Dict[str, str]] = None,
104
- password: Optional[str] = None,
105
- image_resolution_dpi: Optional[int] = None,
106
- browser_canvas: Optional[str] = None,
107
- modality: Optional[Modality] = None,
108
- model: Optional[str] = None,
109
- temperature: Optional[float] = None,
110
- reasoning_effort: Optional[ChatCompletionReasoningEffort] = None,
111
- json_schema: Optional[Dict[str, Any]] = None,
112
- ) -> PreparedRequest:
113
- data: dict[str, Any] = {}
114
-
115
- if link_id is not None:
116
- data["id"] = link_id
117
- if name is not None:
118
- data["name"] = name
119
- if webhook_url is not None:
120
- data["webhook_url"] = webhook_url
121
- if webhook_headers is not None:
122
- data["webhook_headers"] = webhook_headers
123
- if password is not None:
124
- data["password"] = password
125
- if image_resolution_dpi is not None:
126
- data["image_resolution_dpi"] = image_resolution_dpi
127
- if browser_canvas is not None:
128
- data["browser_canvas"] = browser_canvas
129
- if modality is not None:
130
- data["modality"] = modality
131
- if model is not None:
132
- assert_valid_model_extraction(model)
133
- data["model"] = model
134
- if temperature is not None:
135
- data["temperature"] = temperature
136
- if json_schema is not None:
137
- data["json_schema"] = json_schema
138
- if reasoning_effort is not None:
139
- data["reasoning_effort"] = reasoning_effort
140
-
141
- request = UpdateLinkRequest.model_validate(data)
142
- return PreparedRequest(method="PUT", url=f"/v1/deployments/{link_id}", data=request.model_dump(mode='json'))
143
-
144
- def prepare_delete(self, link_id: str) -> PreparedRequest:
145
- return PreparedRequest(method="DELETE", url=f"/v1/processors/automations/links/{link_id}", raise_for_status=True)
146
-
147
- class Links(SyncAPIResource, LinksMixin):
148
- """Extraction Link API wrapper for managing extraction link configurations"""
149
-
150
- def __init__(self, client: Any) -> None:
151
- super().__init__(client=client)
152
-
153
- def create(
154
- self,
155
- name: str,
156
- json_schema: Dict[str, Any],
157
- webhook_url: HttpUrl,
158
- webhook_headers: Optional[Dict[str, str]] = None,
159
- password: str | None = None,
160
- # DocumentExtraction Config
161
- image_resolution_dpi: Optional[int] = None,
162
- browser_canvas: Optional[str] = None,
163
- modality: Modality = "native",
164
- model: str = "gpt-4o-mini",
165
- temperature: float = 0,
166
- reasoning_effort: ChatCompletionReasoningEffort = "medium",
167
- ) -> Link:
168
- """Create a new extraction link configuration.
169
-
170
- Args:
171
- name: Name of the extraction link
172
- json_schema: JSON schema to validate extracted data
173
- webhook_url: Webhook endpoint for forwarding processed files
174
- webhook_headers: Optional HTTP headers for webhook requests
175
- password: Optional password for protected links
176
- image_resolution_dpi: Optional image resolution DPI
177
- browser_canvas: Optional browser canvas
178
- modality: Processing modality (currently only "native" supported)
179
- model: AI model to use for processing
180
- temperature: Model temperature setting
181
- reasoning_effort: The effort level for the model to reason about the input data.
182
- Returns:
183
- Link: The created extraction link configuration
184
- """
185
-
186
- request = self.prepare_create(name, json_schema, webhook_url, webhook_headers, password, image_resolution_dpi, browser_canvas, modality, model, temperature, reasoning_effort)
187
- response = self._client._prepared_request(request)
188
-
189
- print(f"Extraction Link Created. Link available at https://www.uiform.com/dashboard/processors/{response['id']}")
190
- return Link.model_validate(response)
191
-
192
- def list(
193
- self,
194
- before: Optional[str] = None,
195
- after: Optional[str] = None,
196
- limit: Optional[int] = 10,
197
- order: Optional[Literal["asc", "desc"]] = "desc",
198
- # Filtering parameters
199
- link_id: Optional[str] = None,
200
- name: Optional[str] = None,
201
- webhook_url: Optional[str] = None,
202
- schema_id: Optional[str] = None,
203
- schema_data_id: Optional[str] = None,
204
- ) -> ListLinks:
205
- """List extraction link configurations with pagination support.
206
-
207
- Args:
208
- before: Optional cursor for pagination before a specific link ID
209
- after: Optional cursor for pagination after a specific link ID
210
- limit: Optional limit on number of results (max 100)
211
- order: Optional sort order ("asc" or "desc")
212
- link_id: Optional filter by extraction link ID
213
- name: Optional filter by link name
214
- webhook_url: Optional filter by webhook URL
215
- schema_id: Optional filter by schema ID
216
- schema_data_id: Optional filter by schema data ID
217
-
218
- Returns:
219
- ListLinks: Paginated list of extraction link configurations with metadata
220
- """
221
- request = self.prepare_list(before, after, limit, order, link_id, name, webhook_url, schema_id, schema_data_id)
222
- response = self._client._prepared_request(request)
223
- return ListLinks.model_validate(response)
224
-
225
- def get(self, link_id: str) -> Link:
226
- """Get a specific extraction link configuration.
227
-
228
- Args:
229
- link_id: ID of the extraction link
230
-
231
- Returns:
232
- Link: The extraction link configuration
233
- """
234
- request = self.prepare_get(link_id)
235
- response = self._client._prepared_request(request)
236
- return Link.model_validate(response)
237
-
238
- def update(
239
- self,
240
- link_id: str,
241
- name: Optional[str] = None,
242
- webhook_url: Optional[HttpUrl] = None,
243
- webhook_headers: Optional[Dict[str, str]] = None,
244
- password: Optional[str] = None,
245
- image_resolution_dpi: Optional[int] = None,
246
- browser_canvas: Optional[str] = None,
247
- modality: Optional[Modality] = None,
248
- model: Optional[str] = None,
249
- temperature: Optional[float] = None,
250
- reasoning_effort: Optional[ChatCompletionReasoningEffort] = None,
251
- json_schema: Optional[Dict[str, Any]] = None,
252
- ) -> Link:
253
- """Update an extraction link configuration.
254
-
255
- Args:
256
- link_id: ID of the extraction link to update
257
- name: New name for the link
258
- webhook_url: New webhook endpoint URL
259
- webhook_headers: New webhook headers
260
- password: New password for protected links
261
- image_resolution_dpi: New image resolution DPI
262
- browser_canvas: New browser canvas
263
- modality: New processing modality
264
- model: New AI model
265
- temperature: New temperature setting
266
- reasoning_effort: The effort level for the model to reason about the input data.
267
- json_schema: New JSON schema
268
-
269
- Returns:
270
- Link: The updated extraction link configuration
271
- """
272
-
273
- request = self.prepare_update(link_id, name, webhook_url, webhook_headers, password, image_resolution_dpi, browser_canvas, modality, model, temperature, reasoning_effort, json_schema)
274
- response = self._client._prepared_request(request)
275
- return Link.model_validate(response)
276
-
277
- def delete(self, link_id: str) -> None:
278
- """Delete an extraction link configuration.
279
-
280
- Args:
281
- link_id: ID of the extraction link to delete
282
-
283
- Returns:
284
- Dict[str, str]: Response message confirming deletion
285
- """
286
- request = self.prepare_delete(link_id)
287
- self._client._prepared_request(request)
288
-
289
- class AsyncLinks(AsyncAPIResource, LinksMixin):
290
- """Async Extraction Link API wrapper for managing extraction link configurations"""
291
-
292
- def __init__(self, client: Any) -> None:
293
- super().__init__(client=client)
294
-
295
- async def create(
296
- self,
297
- name: str,
298
- json_schema: Dict[str, Any],
299
- webhook_url: HttpUrl,
300
- webhook_headers: Optional[Dict[str, str]] = None,
301
- password: str | None = None,
302
- image_resolution_dpi: Optional[int] = None,
303
- browser_canvas: Optional[str] = None,
304
- modality: Modality = "native",
305
- model: str = "gpt-4o-mini",
306
- temperature: float = 0,
307
- reasoning_effort: ChatCompletionReasoningEffort = "medium",
308
- ) -> Link:
309
- request = self.prepare_create(name, json_schema, webhook_url, webhook_headers, password, image_resolution_dpi, browser_canvas, modality, model, temperature, reasoning_effort)
310
- response = await self._client._prepared_request(request)
311
- print(f"Extraction Link Created. Link available at https://www.uiform.com/dashboard/processors/{response['id']}")
312
- return Link.model_validate(response)
313
-
314
- async def list(
315
- self,
316
- before: Optional[str] = None,
317
- after: Optional[str] = None,
318
- limit: Optional[int] = 10,
319
- order: Optional[Literal["asc", "desc"]] = "desc",
320
- link_id: Optional[str] = None,
321
- name: Optional[str] = None,
322
- webhook_url: Optional[str] = None,
323
- schema_id: Optional[str] = None,
324
- schema_data_id: Optional[str] = None,
325
- ) -> ListLinks:
326
- request = self.prepare_list(before, after, limit, order, link_id, name, webhook_url, schema_id, schema_data_id)
327
- response = await self._client._prepared_request(request)
328
- return ListLinks.model_validate(response)
329
-
330
- async def get(self, link_id: str) -> Link:
331
- request = self.prepare_get(link_id)
332
- response = await self._client._prepared_request(request)
333
- return Link.model_validate(response)
334
-
335
- async def update(
336
- self,
337
- link_id: str,
338
- name: Optional[str] = None,
339
- webhook_url: Optional[HttpUrl] = None,
340
- webhook_headers: Optional[Dict[str, str]] = None,
341
- password: Optional[str] = None,
342
- image_resolution_dpi: Optional[int] = None,
343
- browser_canvas: Optional[str] = None,
344
- modality: Optional[Modality] = None,
345
- model: Optional[str] = None,
346
- temperature: Optional[float] = None,
347
- reasoning_effort: Optional[ChatCompletionReasoningEffort] = None,
348
- json_schema: Optional[Dict[str, Any]] = None,
349
- ) -> Link:
350
- request = self.prepare_update(link_id, name, webhook_url, webhook_headers, password, image_resolution_dpi, browser_canvas, modality, model, temperature, reasoning_effort, json_schema)
351
- response = await self._client._prepared_request(request)
352
- return Link.model_validate(response)
353
-
354
- async def delete(self, link_id: str) -> None:
355
- request = self.prepare_delete(link_id)
356
- await self._client._prepared_request(request)