retab 0.0.35__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.
- {uiform → retab}/_utils/ai_models.py +2 -2
- {uiform → retab}/_utils/benchmarking.py +15 -16
- {uiform → retab}/_utils/chat.py +9 -14
- {uiform → retab}/_utils/display.py +0 -3
- {uiform → retab}/_utils/json_schema.py +9 -14
- {uiform → retab}/_utils/mime.py +11 -14
- {uiform → retab}/_utils/responses.py +9 -3
- {uiform → retab}/_utils/stream_context_managers.py +1 -1
- {uiform → retab}/_utils/usage/usage.py +28 -28
- {uiform → retab}/client.py +32 -31
- {uiform → retab}/resources/consensus/client.py +17 -36
- {uiform → retab}/resources/consensus/completions.py +24 -47
- {uiform → retab}/resources/consensus/completions_stream.py +26 -38
- {uiform → retab}/resources/consensus/responses.py +31 -80
- {uiform → retab}/resources/consensus/responses_stream.py +31 -79
- {uiform → retab}/resources/documents/client.py +59 -45
- {uiform → retab}/resources/documents/extractions.py +181 -90
- {uiform → retab}/resources/evals.py +56 -43
- retab/resources/evaluations/__init__.py +3 -0
- retab/resources/evaluations/client.py +301 -0
- retab/resources/evaluations/documents.py +233 -0
- retab/resources/evaluations/iterations.py +452 -0
- {uiform → retab}/resources/files.py +2 -2
- {uiform → retab}/resources/jsonlUtils.py +220 -216
- retab/resources/models.py +73 -0
- retab/resources/processors/automations/client.py +244 -0
- {uiform → retab}/resources/processors/automations/endpoints.py +77 -118
- retab/resources/processors/automations/links.py +294 -0
- {uiform → retab}/resources/processors/automations/logs.py +30 -19
- {uiform → retab}/resources/processors/automations/mailboxes.py +136 -174
- retab/resources/processors/automations/outlook.py +337 -0
- {uiform → retab}/resources/processors/automations/tests.py +22 -25
- {uiform → retab}/resources/processors/client.py +179 -164
- {uiform → retab}/resources/schemas.py +78 -66
- {uiform → retab}/resources/secrets/external_api_keys.py +1 -5
- retab/resources/secrets/webhook.py +64 -0
- {uiform → retab}/resources/usage.py +39 -2
- {uiform → retab}/types/ai_models.py +13 -13
- {uiform → retab}/types/automations/cron.py +19 -12
- {uiform → retab}/types/automations/endpoints.py +7 -4
- {uiform → retab}/types/automations/links.py +7 -3
- {uiform → retab}/types/automations/mailboxes.py +9 -9
- {uiform → retab}/types/automations/outlook.py +15 -11
- retab/types/browser_canvas.py +3 -0
- {uiform → retab}/types/chat.py +2 -2
- {uiform → retab}/types/completions.py +9 -12
- retab/types/consensus.py +19 -0
- {uiform → retab}/types/db/annotations.py +3 -3
- {uiform → retab}/types/db/files.py +8 -6
- {uiform → retab}/types/documents/create_messages.py +18 -20
- {uiform → retab}/types/documents/extractions.py +69 -24
- {uiform → retab}/types/evals.py +5 -5
- retab/types/evaluations/__init__.py +31 -0
- retab/types/evaluations/documents.py +30 -0
- retab/types/evaluations/iterations.py +112 -0
- retab/types/evaluations/model.py +73 -0
- retab/types/events.py +79 -0
- {uiform → retab}/types/extractions.py +33 -10
- retab/types/inference_settings.py +15 -0
- retab/types/jobs/base.py +54 -0
- retab/types/jobs/batch_annotation.py +12 -0
- {uiform → retab}/types/jobs/evaluation.py +1 -2
- {uiform → retab}/types/logs.py +37 -34
- retab/types/metrics.py +32 -0
- {uiform → retab}/types/mime.py +22 -20
- {uiform → retab}/types/modalities.py +10 -10
- retab/types/predictions.py +19 -0
- {uiform → retab}/types/schemas/enhance.py +4 -2
- {uiform → retab}/types/schemas/evaluate.py +7 -4
- {uiform → retab}/types/schemas/generate.py +6 -3
- {uiform → retab}/types/schemas/layout.py +1 -1
- {uiform → retab}/types/schemas/object.py +13 -14
- {uiform → retab}/types/schemas/templates.py +1 -3
- {uiform → retab}/types/secrets/external_api_keys.py +0 -1
- {uiform → retab}/types/standards.py +18 -1
- {retab-0.0.35.dist-info → retab-0.0.37.dist-info}/METADATA +7 -6
- retab-0.0.37.dist-info/RECORD +107 -0
- retab-0.0.37.dist-info/top_level.txt +1 -0
- retab-0.0.35.dist-info/RECORD +0 -111
- retab-0.0.35.dist-info/top_level.txt +0 -1
- uiform/_utils/benchmarking copy.py +0 -588
- uiform/resources/deployments/__init__.py +0 -9
- uiform/resources/deployments/client.py +0 -78
- uiform/resources/deployments/endpoints.py +0 -322
- uiform/resources/deployments/links.py +0 -452
- uiform/resources/deployments/logs.py +0 -211
- uiform/resources/deployments/mailboxes.py +0 -496
- uiform/resources/deployments/outlook.py +0 -531
- uiform/resources/deployments/tests.py +0 -158
- uiform/resources/models.py +0 -45
- uiform/resources/processors/automations/client.py +0 -78
- uiform/resources/processors/automations/links.py +0 -356
- uiform/resources/processors/automations/outlook.py +0 -444
- uiform/resources/secrets/webhook.py +0 -62
- uiform/types/consensus.py +0 -10
- uiform/types/deployments/cron.py +0 -59
- uiform/types/deployments/endpoints.py +0 -28
- uiform/types/deployments/links.py +0 -36
- uiform/types/deployments/mailboxes.py +0 -67
- uiform/types/deployments/outlook.py +0 -76
- uiform/types/deployments/webhooks.py +0 -21
- uiform/types/events.py +0 -76
- uiform/types/jobs/base.py +0 -150
- uiform/types/jobs/batch_annotation.py +0 -22
- uiform/types/secrets/__init__.py +0 -0
- {uiform → retab}/__init__.py +0 -0
- {uiform → retab}/_resource.py +0 -0
- {uiform → retab}/_utils/__init__.py +0 -0
- {uiform → retab}/_utils/usage/__init__.py +0 -0
- {uiform → retab}/py.typed +0 -0
- {uiform → retab}/resources/__init__.py +0 -0
- {uiform → retab}/resources/consensus/__init__.py +0 -0
- {uiform → retab}/resources/documents/__init__.py +0 -0
- {uiform → retab}/resources/finetuning.py +0 -0
- {uiform → retab}/resources/openai_example.py +0 -0
- {uiform → retab}/resources/processors/__init__.py +0 -0
- {uiform → retab}/resources/processors/automations/__init__.py +0 -0
- {uiform → retab}/resources/prompt_optimization.py +0 -0
- {uiform → retab}/resources/secrets/__init__.py +0 -0
- {uiform → retab}/resources/secrets/client.py +0 -0
- {uiform → retab}/types/__init__.py +0 -0
- {uiform → retab}/types/automations/__init__.py +0 -0
- {uiform → retab}/types/automations/webhooks.py +0 -0
- {uiform → retab}/types/db/__init__.py +0 -0
- {uiform/types/deployments → retab/types/documents}/__init__.py +0 -0
- {uiform → retab}/types/documents/correct_orientation.py +0 -0
- {uiform/types/documents → retab/types/jobs}/__init__.py +0 -0
- {uiform → retab}/types/jobs/finetune.py +0 -0
- {uiform → retab}/types/jobs/prompt_optimization.py +0 -0
- {uiform → retab}/types/jobs/webcrawl.py +0 -0
- {uiform → retab}/types/pagination.py +0 -0
- {uiform/types/jobs → retab/types/schemas}/__init__.py +0 -0
- {uiform/types/schemas → retab/types/secrets}/__init__.py +0 -0
- {retab-0.0.35.dist-info → retab-0.0.37.dist-info}/WHEEL +0 -0
{uiform → retab}/client.py
RENAMED
@@ -1,16 +1,16 @@
|
|
1
1
|
import json
|
2
2
|
import os
|
3
3
|
from types import TracebackType
|
4
|
-
from typing import Any, AsyncIterator,
|
4
|
+
from typing import Any, AsyncIterator, Iterator, Optional
|
5
5
|
|
6
6
|
import backoff
|
7
7
|
import backoff.types
|
8
8
|
import httpx
|
9
|
+
import truststore
|
9
10
|
from pydantic_core import PydanticUndefined
|
10
11
|
|
11
|
-
from .resources import
|
12
|
+
from .resources import consensus, documents, evals, files, finetuning, models, processors, schemas, secrets, usage, evaluations
|
12
13
|
from .types.standards import PreparedRequest
|
13
|
-
import truststore
|
14
14
|
|
15
15
|
|
16
16
|
class MaxRetriesExceeded(Exception):
|
@@ -70,7 +70,6 @@ class BaseUiForm:
|
|
70
70
|
if base_url is None:
|
71
71
|
base_url = os.environ.get("UIFORM_API_BASE_URL", "https://api.uiform.com")
|
72
72
|
|
73
|
-
|
74
73
|
truststore.inject_into_ssl()
|
75
74
|
self.api_key = api_key
|
76
75
|
self.base_url = base_url.rstrip("/")
|
@@ -84,26 +83,26 @@ class BaseUiForm:
|
|
84
83
|
# Only check environment variables if the value is PydanticUndefined
|
85
84
|
if openai_api_key is PydanticUndefined:
|
86
85
|
openai_api_key = os.environ.get("OPENAI_API_KEY")
|
87
|
-
|
86
|
+
|
88
87
|
# if claude_api_key is PydanticUndefined:
|
89
88
|
# claude_api_key = os.environ.get("CLAUDE_API_KEY")
|
90
|
-
|
89
|
+
|
91
90
|
# if xai_api_key is PydanticUndefined:
|
92
91
|
# xai_api_key = os.environ.get("XAI_API_KEY")
|
93
|
-
|
92
|
+
|
94
93
|
if gemini_api_key is PydanticUndefined:
|
95
94
|
gemini_api_key = os.environ.get("GEMINI_API_KEY")
|
96
95
|
|
97
96
|
# Only add headers if the values are actual strings (not None or PydanticUndefined)
|
98
97
|
if openai_api_key and openai_api_key is not PydanticUndefined:
|
99
98
|
self.headers["OpenAI-Api-Key"] = openai_api_key
|
100
|
-
|
99
|
+
|
101
100
|
# if claude_api_key and claude_api_key is not PydanticUndefined:
|
102
101
|
# self.headers["Anthropic-Api-Key"] = claude_api_key
|
103
|
-
|
102
|
+
|
104
103
|
if xai_api_key and xai_api_key is not PydanticUndefined:
|
105
104
|
self.headers["XAI-Api-Key"] = xai_api_key
|
106
|
-
|
105
|
+
|
107
106
|
if gemini_api_key and gemini_api_key is not PydanticUndefined:
|
108
107
|
self.headers["Gemini-Api-Key"] = gemini_api_key
|
109
108
|
|
@@ -126,12 +125,12 @@ class BaseUiForm:
|
|
126
125
|
|
127
126
|
def _parse_response(self, response: httpx.Response) -> Any:
|
128
127
|
"""Parse response based on content-type.
|
129
|
-
|
128
|
+
|
130
129
|
Returns:
|
131
130
|
Any: Parsed JSON object for JSON responses, raw text string for text responses
|
132
131
|
"""
|
133
132
|
content_type = response.headers.get("content-type", "")
|
134
|
-
|
133
|
+
|
135
134
|
# Check if it's a JSON response
|
136
135
|
if "application/json" in content_type or "application/stream+json" in content_type:
|
137
136
|
return response.json()
|
@@ -198,6 +197,7 @@ class UiForm(BaseUiForm):
|
|
198
197
|
|
199
198
|
self.client = httpx.Client(timeout=self.timeout)
|
200
199
|
self.evals = evals.Evals(client=self)
|
200
|
+
self.evaluations = evaluations.Evaluations(client=self)
|
201
201
|
self.files = files.Files(client=self)
|
202
202
|
self.fine_tuning = finetuning.FineTuning(client=self)
|
203
203
|
# self.prompt_optimization = prompt_optimization.PromptOptimization(client=self)
|
@@ -247,7 +247,7 @@ class UiForm(BaseUiForm):
|
|
247
247
|
"params": params,
|
248
248
|
"headers": self._get_headers(idempotency_key),
|
249
249
|
}
|
250
|
-
|
250
|
+
|
251
251
|
# Handle different content types
|
252
252
|
if files or form_data:
|
253
253
|
# For multipart/form-data requests
|
@@ -262,7 +262,7 @@ class UiForm(BaseUiForm):
|
|
262
262
|
elif data:
|
263
263
|
# For JSON requests
|
264
264
|
request_kwargs["json"] = data
|
265
|
-
|
265
|
+
|
266
266
|
response = self.client.request(**request_kwargs)
|
267
267
|
self._validate_response(response)
|
268
268
|
return self._parse_response(response)
|
@@ -314,7 +314,7 @@ class UiForm(BaseUiForm):
|
|
314
314
|
"params": params,
|
315
315
|
"headers": self._get_headers(idempotency_key),
|
316
316
|
}
|
317
|
-
|
317
|
+
|
318
318
|
# Handle different content types
|
319
319
|
if files or form_data:
|
320
320
|
# For multipart/form-data requests
|
@@ -329,10 +329,10 @@ class UiForm(BaseUiForm):
|
|
329
329
|
elif data:
|
330
330
|
# For JSON requests
|
331
331
|
stream_kwargs["json"] = data
|
332
|
-
|
332
|
+
|
333
333
|
with self.client.stream(**stream_kwargs) as response_ctx_manager:
|
334
334
|
self._validate_response(response_ctx_manager)
|
335
|
-
|
335
|
+
|
336
336
|
content_type = response_ctx_manager.headers.get("content-type", "")
|
337
337
|
is_json_stream = "application/json" in content_type or "application/stream+json" in content_type
|
338
338
|
is_text_stream = "text/plain" in content_type or ("text/" in content_type and not is_json_stream)
|
@@ -340,7 +340,7 @@ class UiForm(BaseUiForm):
|
|
340
340
|
for chunk in response_ctx_manager.iter_lines():
|
341
341
|
if not chunk:
|
342
342
|
continue
|
343
|
-
|
343
|
+
|
344
344
|
if is_json_stream:
|
345
345
|
try:
|
346
346
|
yield json.loads(chunk)
|
@@ -375,7 +375,7 @@ class UiForm(BaseUiForm):
|
|
375
375
|
form_data=request.form_data,
|
376
376
|
files=request.files,
|
377
377
|
idempotency_key=request.idempotency_key,
|
378
|
-
raise_for_status=request.raise_for_status
|
378
|
+
raise_for_status=request.raise_for_status,
|
379
379
|
)
|
380
380
|
|
381
381
|
def _prepared_request_stream(self, request: PreparedRequest) -> Iterator[Any]:
|
@@ -387,7 +387,7 @@ class UiForm(BaseUiForm):
|
|
387
387
|
form_data=request.form_data,
|
388
388
|
files=request.files,
|
389
389
|
idempotency_key=request.idempotency_key,
|
390
|
-
raise_for_status=request.raise_for_status
|
390
|
+
raise_for_status=request.raise_for_status,
|
391
391
|
):
|
392
392
|
yield item
|
393
393
|
|
@@ -466,6 +466,7 @@ class AsyncUiForm(BaseUiForm):
|
|
466
466
|
self.client = httpx.AsyncClient(timeout=self.timeout)
|
467
467
|
|
468
468
|
self.evals = evals.AsyncEvals(client=self)
|
469
|
+
self.evaluations = evaluations.AsyncEvaluations(client=self)
|
469
470
|
self.files = files.AsyncFiles(client=self)
|
470
471
|
self.fine_tuning = finetuning.AsyncFineTuning(client=self)
|
471
472
|
# self.prompt_optimization = prompt_optimization.AsyncPromptOptimization(client=self)
|
@@ -479,12 +480,12 @@ class AsyncUiForm(BaseUiForm):
|
|
479
480
|
|
480
481
|
def _parse_response(self, response: httpx.Response) -> Any:
|
481
482
|
"""Parse response based on content-type.
|
482
|
-
|
483
|
+
|
483
484
|
Returns:
|
484
485
|
Any: Parsed JSON object for JSON responses, raw text string for text responses
|
485
486
|
"""
|
486
487
|
content_type = response.headers.get("content-type", "")
|
487
|
-
|
488
|
+
|
488
489
|
# Check if it's a JSON response
|
489
490
|
if "application/json" in content_type or "application/stream+json" in content_type:
|
490
491
|
return response.json()
|
@@ -536,7 +537,7 @@ class AsyncUiForm(BaseUiForm):
|
|
536
537
|
"params": params,
|
537
538
|
"headers": self._get_headers(idempotency_key),
|
538
539
|
}
|
539
|
-
|
540
|
+
|
540
541
|
# Handle different content types
|
541
542
|
if files or form_data:
|
542
543
|
# For multipart/form-data requests
|
@@ -551,7 +552,7 @@ class AsyncUiForm(BaseUiForm):
|
|
551
552
|
elif data:
|
552
553
|
# For JSON requests
|
553
554
|
request_kwargs["json"] = data
|
554
|
-
|
555
|
+
|
555
556
|
response = await self.client.request(**request_kwargs)
|
556
557
|
self._validate_response(response)
|
557
558
|
return self._parse_response(response)
|
@@ -602,7 +603,7 @@ class AsyncUiForm(BaseUiForm):
|
|
602
603
|
"params": params,
|
603
604
|
"headers": self._get_headers(idempotency_key),
|
604
605
|
}
|
605
|
-
|
606
|
+
|
606
607
|
# Handle different content types
|
607
608
|
if files or form_data:
|
608
609
|
# For multipart/form-data requests
|
@@ -617,18 +618,18 @@ class AsyncUiForm(BaseUiForm):
|
|
617
618
|
elif data:
|
618
619
|
# For JSON requests
|
619
620
|
stream_kwargs["json"] = data
|
620
|
-
|
621
|
+
|
621
622
|
async with self.client.stream(**stream_kwargs) as response_ctx_manager:
|
622
623
|
self._validate_response(response_ctx_manager)
|
623
|
-
|
624
|
+
|
624
625
|
content_type = response_ctx_manager.headers.get("content-type", "")
|
625
626
|
is_json_stream = "application/json" in content_type or "application/stream+json" in content_type
|
626
627
|
is_text_stream = "text/plain" in content_type or ("text/" in content_type and not is_json_stream)
|
627
|
-
|
628
|
+
|
628
629
|
async for chunk in response_ctx_manager.aiter_lines():
|
629
630
|
if not chunk:
|
630
631
|
continue
|
631
|
-
|
632
|
+
|
632
633
|
if is_json_stream:
|
633
634
|
try:
|
634
635
|
yield json.loads(chunk)
|
@@ -662,7 +663,7 @@ class AsyncUiForm(BaseUiForm):
|
|
662
663
|
form_data=request.form_data,
|
663
664
|
files=request.files,
|
664
665
|
idempotency_key=request.idempotency_key,
|
665
|
-
raise_for_status=request.raise_for_status
|
666
|
+
raise_for_status=request.raise_for_status,
|
666
667
|
)
|
667
668
|
|
668
669
|
async def _prepared_request_stream(self, request: PreparedRequest) -> AsyncIterator[Any]:
|
@@ -674,7 +675,7 @@ class AsyncUiForm(BaseUiForm):
|
|
674
675
|
form_data=request.form_data,
|
675
676
|
files=request.files,
|
676
677
|
idempotency_key=request.idempotency_key,
|
677
|
-
raise_for_status=request.raise_for_status
|
678
|
+
raise_for_status=request.raise_for_status,
|
678
679
|
):
|
679
680
|
yield item
|
680
681
|
|
@@ -1,15 +1,13 @@
|
|
1
1
|
from typing import Any, Dict, List, Literal, Optional
|
2
2
|
|
3
|
-
from pydantic import BaseModel, Field
|
4
|
-
|
5
3
|
from ..._resource import AsyncAPIResource, SyncAPIResource
|
4
|
+
from ...types.consensus import ReconciliationResponse, ReconciliationRequest
|
6
5
|
from ...types.standards import PreparedRequest
|
7
6
|
from .completions import AsyncCompletions, Completions
|
8
7
|
from .responses import AsyncResponses, Responses
|
9
|
-
from ...types.consensus import ReconciliationResponse
|
10
8
|
|
11
|
-
class BaseConsensusMixin:
|
12
9
|
|
10
|
+
class BaseConsensusMixin:
|
13
11
|
def _prepare_reconcile(
|
14
12
|
self,
|
15
13
|
list_dicts: List[Dict[str, Any]],
|
@@ -17,21 +15,15 @@ class BaseConsensusMixin:
|
|
17
15
|
mode: Literal["direct", "aligned"] = "direct",
|
18
16
|
idempotency_key: str | None = None,
|
19
17
|
) -> PreparedRequest:
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
if reference_schema is not None:
|
26
|
-
data["reference_schema"] = reference_schema
|
27
|
-
|
28
|
-
return PreparedRequest(
|
29
|
-
method="POST",
|
30
|
-
url="/v1/consensus/reconcile",
|
31
|
-
data=data,
|
32
|
-
idempotency_key=idempotency_key
|
18
|
+
request = ReconciliationRequest(
|
19
|
+
list_dicts=list_dicts,
|
20
|
+
reference_schema=reference_schema,
|
21
|
+
mode=mode,
|
33
22
|
)
|
34
23
|
|
24
|
+
return PreparedRequest(method="POST", url="/v1/consensus/reconcile", data=request.model_dump(), idempotency_key=idempotency_key)
|
25
|
+
|
26
|
+
|
35
27
|
class Consensus(SyncAPIResource, BaseConsensusMixin):
|
36
28
|
"""Consensus API wrapper for synchronous operations"""
|
37
29
|
|
@@ -49,25 +41,20 @@ class Consensus(SyncAPIResource, BaseConsensusMixin):
|
|
49
41
|
) -> ReconciliationResponse:
|
50
42
|
"""
|
51
43
|
Reconcile multiple dictionaries to produce a single unified consensus dictionary.
|
52
|
-
|
44
|
+
|
53
45
|
Args:
|
54
46
|
list_dicts: List of dictionaries to reconcile
|
55
47
|
reference_schema: Optional schema to validate dictionaries against
|
56
48
|
mode: Mode for consensus computation ("direct" or "aligned")
|
57
49
|
idempotency_key: Optional idempotency key for the request
|
58
|
-
|
50
|
+
|
59
51
|
Returns:
|
60
52
|
Dict containing the consensus dictionary and consensus likelihoods
|
61
|
-
|
53
|
+
|
62
54
|
Raises:
|
63
55
|
UiformAPIError: If the API request fails
|
64
56
|
"""
|
65
|
-
request = self._prepare_reconcile(
|
66
|
-
list_dicts,
|
67
|
-
reference_schema,
|
68
|
-
mode,
|
69
|
-
idempotency_key
|
70
|
-
)
|
57
|
+
request = self._prepare_reconcile(list_dicts, reference_schema, mode, idempotency_key)
|
71
58
|
response = self._client._prepared_request(request)
|
72
59
|
return ReconciliationResponse.model_validate(response)
|
73
60
|
|
@@ -80,7 +67,6 @@ class AsyncConsensus(AsyncAPIResource, BaseConsensusMixin):
|
|
80
67
|
self.completions = AsyncCompletions(client=client)
|
81
68
|
self.responses = AsyncResponses(client=client)
|
82
69
|
|
83
|
-
|
84
70
|
async def reconcile(
|
85
71
|
self,
|
86
72
|
list_dicts: List[Dict[str, Any]],
|
@@ -90,25 +76,20 @@ class AsyncConsensus(AsyncAPIResource, BaseConsensusMixin):
|
|
90
76
|
) -> ReconciliationResponse:
|
91
77
|
"""
|
92
78
|
Reconcile multiple dictionaries to produce a single unified consensus dictionary asynchronously.
|
93
|
-
|
79
|
+
|
94
80
|
Args:
|
95
81
|
list_dicts: List of dictionaries to reconcile
|
96
82
|
reference_schema: Optional schema to validate dictionaries against
|
97
83
|
mode: Mode for consensus computation ("direct" or "aligned")
|
98
84
|
idempotency_key: Optional idempotency key for the request
|
99
|
-
|
85
|
+
|
100
86
|
Returns:
|
101
87
|
Dict containing the consensus dictionary and consensus likelihoods
|
102
|
-
|
88
|
+
|
103
89
|
Raises:
|
104
90
|
UiformAPIError: If the API request fails
|
105
91
|
"""
|
106
|
-
request = self._prepare_reconcile(
|
107
|
-
list_dicts,
|
108
|
-
reference_schema,
|
109
|
-
mode,
|
110
|
-
idempotency_key
|
111
|
-
)
|
92
|
+
request = self._prepare_reconcile(list_dicts, reference_schema, mode, idempotency_key)
|
112
93
|
response = await self._client._prepared_request(request)
|
113
94
|
|
114
95
|
return ReconciliationResponse.model_validate(response)
|
@@ -1,28 +1,19 @@
|
|
1
|
-
import json
|
2
|
-
from pathlib import Path
|
3
|
-
from typing import Any, AsyncGenerator, Generator
|
4
|
-
|
5
1
|
from openai.types.chat.chat_completion_reasoning_effort import ChatCompletionReasoningEffort
|
6
|
-
from openai.types.chat.parsed_chat_completion import ParsedChatCompletionMessage
|
7
2
|
from openai.types.shared_params.response_format_json_schema import ResponseFormatJSONSchema
|
8
|
-
#from openai.lib._parsing import ResponseFormatT
|
9
|
-
from pydantic import BaseModel as ResponseFormatT
|
10
3
|
|
4
|
+
# from openai.lib._parsing import ResponseFormatT
|
5
|
+
from pydantic import BaseModel as ResponseFormatT
|
11
6
|
|
12
7
|
from ..._resource import AsyncAPIResource, SyncAPIResource
|
13
8
|
from ..._utils.ai_models import assert_valid_model_extraction
|
14
|
-
from ..._utils.json_schema import load_json_schema, unflatten_dict
|
15
|
-
from ..._utils.stream_context_managers import as_async_context_manager, as_context_manager
|
16
9
|
from ...types.chat import ChatCompletionUiformMessage
|
17
10
|
from ...types.completions import UiChatCompletionsRequest
|
18
|
-
from ...types.documents.extractions import UiParsedChatCompletion
|
19
|
-
from ...types.standards import PreparedRequest
|
11
|
+
from ...types.documents.extractions import UiParsedChatCompletion
|
20
12
|
from ...types.schemas.object import Schema
|
21
|
-
|
13
|
+
from ...types.standards import PreparedRequest
|
22
14
|
|
23
15
|
|
24
16
|
class BaseCompletionsMixin:
|
25
|
-
|
26
17
|
def prepare_parse(
|
27
18
|
self,
|
28
19
|
response_format: type[ResponseFormatT],
|
@@ -40,9 +31,10 @@ class BaseCompletionsMixin:
|
|
40
31
|
|
41
32
|
schema_obj = Schema(json_schema=json_schema)
|
42
33
|
|
43
|
-
|
44
|
-
|
45
|
-
|
34
|
+
request = UiChatCompletionsRequest(
|
35
|
+
model=model,
|
36
|
+
messages=messages,
|
37
|
+
response_format={
|
46
38
|
"type": "json_schema",
|
47
39
|
"json_schema": {
|
48
40
|
"name": schema_obj.id,
|
@@ -50,18 +42,12 @@ class BaseCompletionsMixin:
|
|
50
42
|
"strict": True,
|
51
43
|
},
|
52
44
|
},
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
# Validate DocumentAPIRequest data (raises exception if invalid)
|
61
|
-
ui_chat_completions_request = UiChatCompletionsRequest.model_validate(data)
|
62
|
-
|
63
|
-
return PreparedRequest(method="POST", url="/v1/completions", data=ui_chat_completions_request.model_dump(), idempotency_key=idempotency_key)
|
64
|
-
|
45
|
+
temperature=temperature,
|
46
|
+
stream=stream,
|
47
|
+
reasoning_effort=reasoning_effort,
|
48
|
+
n_consensus=n_consensus,
|
49
|
+
)
|
50
|
+
return PreparedRequest(method="POST", url="/v1/completions", data=request.model_dump(), idempotency_key=idempotency_key)
|
65
51
|
|
66
52
|
def prepare_create(
|
67
53
|
self,
|
@@ -74,16 +60,16 @@ class BaseCompletionsMixin:
|
|
74
60
|
n_consensus: int,
|
75
61
|
idempotency_key: str | None = None,
|
76
62
|
) -> PreparedRequest:
|
77
|
-
|
78
63
|
json_schema = response_format["json_schema"].get("schema")
|
79
64
|
|
80
65
|
assert isinstance(json_schema, dict), f"json_schema must be a dictionary, got {type(json_schema)}"
|
81
66
|
|
82
67
|
schema_obj = Schema(json_schema=json_schema)
|
83
68
|
|
84
|
-
|
85
|
-
|
86
|
-
|
69
|
+
request = UiChatCompletionsRequest(
|
70
|
+
model=model,
|
71
|
+
messages=messages,
|
72
|
+
response_format={
|
87
73
|
"type": "json_schema",
|
88
74
|
"json_schema": {
|
89
75
|
"name": schema_obj.id,
|
@@ -91,17 +77,12 @@ class BaseCompletionsMixin:
|
|
91
77
|
"strict": True,
|
92
78
|
},
|
93
79
|
},
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
# Validate DocumentAPIRequest data (raises exception if invalid)
|
102
|
-
ui_chat_completions_request = UiChatCompletionsRequest.model_validate(data)
|
103
|
-
|
104
|
-
return PreparedRequest(method="POST", url="/v1/completions", data=ui_chat_completions_request.model_dump(), idempotency_key=idempotency_key)
|
80
|
+
temperature=temperature,
|
81
|
+
stream=stream,
|
82
|
+
reasoning_effort=reasoning_effort,
|
83
|
+
n_consensus=n_consensus,
|
84
|
+
)
|
85
|
+
return PreparedRequest(method="POST", url="/v1/completions", data=request.model_dump(), idempotency_key=idempotency_key)
|
105
86
|
|
106
87
|
|
107
88
|
class Completions(SyncAPIResource, BaseCompletionsMixin):
|
@@ -137,7 +118,6 @@ class Completions(SyncAPIResource, BaseCompletionsMixin):
|
|
137
118
|
|
138
119
|
return UiParsedChatCompletion.model_validate(response)
|
139
120
|
|
140
|
-
|
141
121
|
def parse(
|
142
122
|
self,
|
143
123
|
response_format: type[ResponseFormatT],
|
@@ -210,9 +190,6 @@ class AsyncCompletions(AsyncAPIResource, BaseCompletionsMixin):
|
|
210
190
|
response = await self._client._prepared_request(request)
|
211
191
|
return UiParsedChatCompletion.model_validate(response)
|
212
192
|
|
213
|
-
|
214
|
-
|
215
|
-
|
216
193
|
async def parse(
|
217
194
|
self,
|
218
195
|
response_format: type[ResponseFormatT],
|
@@ -1,28 +1,25 @@
|
|
1
1
|
import json
|
2
|
-
from
|
3
|
-
from typing import Any, AsyncGenerator, Generator
|
2
|
+
from typing import AsyncGenerator, Generator
|
4
3
|
|
5
4
|
from openai.types.chat.chat_completion_reasoning_effort import ChatCompletionReasoningEffort
|
6
5
|
from openai.types.chat.parsed_chat_completion import ParsedChatCompletionMessage
|
7
6
|
from openai.types.shared_params.response_format_json_schema import ResponseFormatJSONSchema
|
8
|
-
#from openai.lib._parsing import ResponseFormatT
|
9
|
-
from pydantic import BaseModel as ResponseFormatT
|
10
7
|
|
8
|
+
# from openai.lib._parsing import ResponseFormatT
|
9
|
+
from pydantic import BaseModel as ResponseFormatT
|
11
10
|
|
12
11
|
from ..._resource import AsyncAPIResource, SyncAPIResource
|
13
12
|
from ..._utils.ai_models import assert_valid_model_extraction
|
14
|
-
from ..._utils.json_schema import
|
13
|
+
from ..._utils.json_schema import unflatten_dict
|
15
14
|
from ..._utils.stream_context_managers import as_async_context_manager, as_context_manager
|
16
15
|
from ...types.chat import ChatCompletionUiformMessage
|
17
16
|
from ...types.completions import UiChatCompletionsRequest
|
18
17
|
from ...types.documents.extractions import UiParsedChatCompletion, UiParsedChatCompletionChunk, UiParsedChoice
|
19
|
-
from ...types.standards import PreparedRequest
|
20
18
|
from ...types.schemas.object import Schema
|
21
|
-
|
19
|
+
from ...types.standards import PreparedRequest
|
22
20
|
|
23
21
|
|
24
22
|
class BaseCompletionsMixin:
|
25
|
-
|
26
23
|
def prepare_parse(
|
27
24
|
self,
|
28
25
|
response_format: type[ResponseFormatT],
|
@@ -37,12 +34,11 @@ class BaseCompletionsMixin:
|
|
37
34
|
assert_valid_model_extraction(model)
|
38
35
|
|
39
36
|
json_schema = response_format.model_json_schema()
|
40
|
-
|
41
37
|
schema_obj = Schema(json_schema=json_schema)
|
42
38
|
|
43
|
-
|
44
|
-
|
45
|
-
|
39
|
+
request = UiChatCompletionsRequest(
|
40
|
+
messages=messages,
|
41
|
+
response_format={
|
46
42
|
"type": "json_schema",
|
47
43
|
"json_schema": {
|
48
44
|
"name": schema_obj.id,
|
@@ -50,18 +46,14 @@ class BaseCompletionsMixin:
|
|
50
46
|
"strict": True,
|
51
47
|
},
|
52
48
|
},
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
# Validate DocumentAPIRequest data (raises exception if invalid)
|
61
|
-
ui_chat_completions_request = UiChatCompletionsRequest.model_validate(data)
|
62
|
-
|
63
|
-
return PreparedRequest(method="POST", url="/v1/completions", data=ui_chat_completions_request.model_dump(), idempotency_key=idempotency_key)
|
49
|
+
model=model,
|
50
|
+
temperature=temperature,
|
51
|
+
stream=stream,
|
52
|
+
reasoning_effort=reasoning_effort,
|
53
|
+
n_consensus=n_consensus,
|
54
|
+
)
|
64
55
|
|
56
|
+
return PreparedRequest(method="POST", url="/v1/completions", data=request.model_dump(), idempotency_key=idempotency_key)
|
65
57
|
|
66
58
|
def prepare_create(
|
67
59
|
self,
|
@@ -74,16 +66,17 @@ class BaseCompletionsMixin:
|
|
74
66
|
n_consensus: int,
|
75
67
|
idempotency_key: str | None = None,
|
76
68
|
) -> PreparedRequest:
|
77
|
-
|
78
69
|
json_schema = response_format["json_schema"].get("schema")
|
79
70
|
|
80
71
|
assert isinstance(json_schema, dict), f"json_schema must be a dictionary, got {type(json_schema)}"
|
81
72
|
|
82
73
|
schema_obj = Schema(json_schema=json_schema)
|
83
74
|
|
84
|
-
data
|
85
|
-
|
86
|
-
|
75
|
+
# Validate DocumentAPIRequest data (raises exception if invalid)
|
76
|
+
request = UiChatCompletionsRequest(
|
77
|
+
model=model,
|
78
|
+
messages=messages,
|
79
|
+
response_format={
|
87
80
|
"type": "json_schema",
|
88
81
|
"json_schema": {
|
89
82
|
"name": schema_obj.id,
|
@@ -91,17 +84,13 @@ class BaseCompletionsMixin:
|
|
91
84
|
"strict": True,
|
92
85
|
},
|
93
86
|
},
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
}
|
100
|
-
|
101
|
-
# Validate DocumentAPIRequest data (raises exception if invalid)
|
102
|
-
ui_chat_completions_request = UiChatCompletionsRequest.model_validate(data)
|
87
|
+
temperature=temperature,
|
88
|
+
stream=stream,
|
89
|
+
reasoning_effort=reasoning_effort,
|
90
|
+
n_consensus=n_consensus,
|
91
|
+
)
|
103
92
|
|
104
|
-
return PreparedRequest(method="POST", url="/v1/completions", data=
|
93
|
+
return PreparedRequest(method="POST", url="/v1/completions", data=request.model_dump(), idempotency_key=idempotency_key)
|
105
94
|
|
106
95
|
|
107
96
|
class Completions(SyncAPIResource, BaseCompletionsMixin):
|
@@ -193,7 +182,6 @@ class Completions(SyncAPIResource, BaseCompletionsMixin):
|
|
193
182
|
class AsyncCompletions(AsyncAPIResource, BaseCompletionsMixin):
|
194
183
|
"""Multi-provider Completions API wrapper for asynchronous usage."""
|
195
184
|
|
196
|
-
|
197
185
|
@as_async_context_manager
|
198
186
|
async def stream(
|
199
187
|
self,
|