unique-sdk 2026.44.0.dev14__tar.gz → 2026.44.0.dev15__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/PKG-INFO +1 -1
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/pyproject.toml +1 -1
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/__init__.py +1 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/_api_requestor.py +45 -20
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/_error.py +18 -5
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/_util.py +50 -32
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/README.md +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/_api_resource.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/_api_version.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/_http_client.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/_list_object.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/_object_classes.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/_request_options.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/_unique_object.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/_unique_ql.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/_unique_response.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/_version.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/_webhook.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/api_resources/__init__.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/api_resources/_acronyms.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/api_resources/_agentic_table.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/api_resources/_analytics_order.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/api_resources/_benchmarking.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/api_resources/_briefing.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/api_resources/_chat_completion.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/api_resources/_content.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/api_resources/_context_memory.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/api_resources/_elicitation.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/api_resources/_embedding.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/api_resources/_event.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/api_resources/_folder.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/api_resources/_group.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/api_resources/_integrated.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/api_resources/_llm_models.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/api_resources/_mcp.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/api_resources/_message.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/api_resources/_message_assessment.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/api_resources/_message_execution.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/api_resources/_message_log.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/api_resources/_message_tool.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/api_resources/_module.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/api_resources/_scheduled_task.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/api_resources/_search.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/api_resources/_search_string.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/api_resources/_short_term_memory.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/api_resources/_space.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/api_resources/_user.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/api_resources/_web_search.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/cli/__init__.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/cli/__main__.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/cli/cli.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/cli/commands/__init__.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/cli/commands/_citation_manifest.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/cli/commands/agentic_table.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/cli/commands/agentic_table_write.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/cli/commands/browser.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/cli/commands/cite_file.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/cli/commands/elicitation.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/cli/commands/files.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/cli/commands/folders.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/cli/commands/mcp.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/cli/commands/navigation.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/cli/commands/read.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/cli/commands/scheduled_tasks.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/cli/commands/search.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/cli/commands/subagent.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/cli/commands/web_search.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/cli/commands/web_search_config.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/cli/config.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/cli/formatting.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/cli/identity.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/cli/metadata_filter.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/cli/paths.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/cli/shell.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/cli/skills/unique-cli-agentic-table/SKILL.md +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/cli/skills/unique-cli-elicitation/SKILL.md +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/cli/skills/unique-cli-file-management/SKILL.md +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/cli/skills/unique-cli-mcp/SKILL.md +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/cli/skills/unique-cli-scheduled-tasks/SKILL.md +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/cli/skills/unique-cli-search/SKILL.md +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/cli/skills/unique-cli-subagent/SKILL.md +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/cli/skills/unique-cli-uploaded-search/SKILL.md +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/cli/skills/unique-cli-web-search/SKILL.md +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/cli/state.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/cli/workspace.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/utils/analytics_order_run.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/utils/benchmarking_run.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/utils/chat_history.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/utils/chat_in_space.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/utils/file_io.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/utils/sources.py +0 -0
- {unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/utils/token.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: unique-sdk
|
|
3
|
-
Version: 2026.44.0.
|
|
3
|
+
Version: 2026.44.0.dev15
|
|
4
4
|
Summary:
|
|
5
5
|
Author: Martin Fadler, Konstantin Krauss, Andreas Hauri
|
|
6
6
|
Author-email: Martin Fadler <martin.fadler@unique.ch>, Konstantin Krauss <konstantin@unique.ch>, Andreas Hauri <andreas@unique.ch>
|
|
@@ -34,6 +34,7 @@ from unique_sdk._error import APIConnectionError as APIConnectionError
|
|
|
34
34
|
from unique_sdk._error import APIError as APIError
|
|
35
35
|
from unique_sdk._error import AuthenticationError as AuthenticationError
|
|
36
36
|
from unique_sdk._error import InvalidRequestError as InvalidRequestError
|
|
37
|
+
from unique_sdk._error import RateLimitError as RateLimitError
|
|
37
38
|
from unique_sdk._error import (
|
|
38
39
|
SignatureVerificationError as SignatureVerificationError,
|
|
39
40
|
)
|
|
@@ -392,7 +392,15 @@ class APIRequestor(object):
|
|
|
392
392
|
cause = error_data.get("cause", {})
|
|
393
393
|
if isinstance(cause, str):
|
|
394
394
|
cause = {"error": {"message": cause}, "status": rcode}
|
|
395
|
-
|
|
395
|
+
|
|
396
|
+
cause_error = cause.get("error") or {}
|
|
397
|
+
cause_code = cause_error.get("code")
|
|
398
|
+
cause_message = cause_error.get("message")
|
|
399
|
+
|
|
400
|
+
message = error_data.get("message") or cause_message
|
|
401
|
+
code = error_data.get("code") or cause_code
|
|
402
|
+
params = error_data.get("params") or cause_error.get("params")
|
|
403
|
+
status = rcode if error_data.get("code") else cause.get("status", rcode)
|
|
396
404
|
|
|
397
405
|
_util.log_info(
|
|
398
406
|
"Unique error received",
|
|
@@ -402,46 +410,63 @@ class APIRequestor(object):
|
|
|
402
410
|
error_params=_util.redacted_error_params(error_data.get("params")),
|
|
403
411
|
)
|
|
404
412
|
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
413
|
+
original_error = None
|
|
414
|
+
if cause_code or cause_message:
|
|
415
|
+
original_error = (
|
|
416
|
+
f"{cause_code or '<Unknown code>'}: {cause_message or '<No message>'}"
|
|
417
|
+
)
|
|
409
418
|
|
|
410
|
-
if status
|
|
411
|
-
return _error.
|
|
412
|
-
message=
|
|
413
|
-
params=
|
|
414
|
-
code=
|
|
419
|
+
if status == 429:
|
|
420
|
+
return _error.RateLimitError(
|
|
421
|
+
message=message,
|
|
422
|
+
params=params,
|
|
423
|
+
code=code,
|
|
415
424
|
http_body=rbody,
|
|
416
425
|
http_status=rcode,
|
|
417
426
|
json_body=resp,
|
|
418
427
|
headers=rheaders,
|
|
419
428
|
original_error=original_error,
|
|
420
429
|
)
|
|
421
|
-
|
|
422
|
-
return _error.
|
|
423
|
-
message=
|
|
430
|
+
if status in [400, 404]:
|
|
431
|
+
return _error.InvalidRequestError(
|
|
432
|
+
message=message,
|
|
433
|
+
params=params,
|
|
434
|
+
code=code,
|
|
424
435
|
http_body=rbody,
|
|
425
|
-
http_status=
|
|
436
|
+
http_status=rcode,
|
|
426
437
|
json_body=resp,
|
|
427
438
|
headers=rheaders,
|
|
428
439
|
original_error=original_error,
|
|
429
440
|
)
|
|
430
|
-
|
|
431
|
-
return _error.
|
|
432
|
-
message=
|
|
441
|
+
if status == 401:
|
|
442
|
+
return _error.AuthenticationError(
|
|
443
|
+
message=message,
|
|
433
444
|
http_body=rbody,
|
|
434
445
|
http_status=status,
|
|
435
446
|
json_body=resp,
|
|
436
447
|
headers=rheaders,
|
|
448
|
+
code=code,
|
|
437
449
|
original_error=original_error,
|
|
450
|
+
params=params,
|
|
438
451
|
)
|
|
439
|
-
|
|
440
|
-
return _error.
|
|
441
|
-
message=
|
|
452
|
+
if status == 403:
|
|
453
|
+
return _error.PermissionError(
|
|
454
|
+
message=message,
|
|
442
455
|
http_body=rbody,
|
|
443
456
|
http_status=status,
|
|
444
457
|
json_body=resp,
|
|
445
458
|
headers=rheaders,
|
|
459
|
+
code=code,
|
|
446
460
|
original_error=original_error,
|
|
461
|
+
params=params,
|
|
447
462
|
)
|
|
463
|
+
return _error.APIError(
|
|
464
|
+
message=message,
|
|
465
|
+
http_body=rbody,
|
|
466
|
+
http_status=status,
|
|
467
|
+
json_body=resp,
|
|
468
|
+
headers=rheaders,
|
|
469
|
+
code=code,
|
|
470
|
+
original_error=original_error,
|
|
471
|
+
params=params,
|
|
472
|
+
)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import cast
|
|
1
|
+
from typing import Any, cast
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
class UniqueError(Exception):
|
|
@@ -10,6 +10,7 @@ class UniqueError(Exception):
|
|
|
10
10
|
code: str | None
|
|
11
11
|
request_id: str | None
|
|
12
12
|
original_error: Exception | str | None
|
|
13
|
+
params: dict[str, Any] | str | None
|
|
13
14
|
|
|
14
15
|
def __init__(
|
|
15
16
|
self,
|
|
@@ -20,6 +21,7 @@ class UniqueError(Exception):
|
|
|
20
21
|
headers: dict[str, str] | None = None,
|
|
21
22
|
code: str | None = None,
|
|
22
23
|
original_error: Exception | str | None = None,
|
|
24
|
+
params: dict[str, Any] | str | None = None,
|
|
23
25
|
):
|
|
24
26
|
super(UniqueError, self).__init__(message)
|
|
25
27
|
|
|
@@ -41,6 +43,7 @@ class UniqueError(Exception):
|
|
|
41
43
|
self.code = code
|
|
42
44
|
self.request_id = self.headers.get("request-id", None)
|
|
43
45
|
self.original_error = original_error
|
|
46
|
+
self.params = params
|
|
44
47
|
|
|
45
48
|
def __str__(self):
|
|
46
49
|
msg = self._message or "<empty message>"
|
|
@@ -51,7 +54,7 @@ class UniqueError(Exception):
|
|
|
51
54
|
|
|
52
55
|
class UniqueErrorWithParamsCode(UniqueError):
|
|
53
56
|
# str included: InvalidRequestError callers pass plain strings (e.g. "id")
|
|
54
|
-
params: dict[str,
|
|
57
|
+
params: dict[str, Any] | str | None
|
|
55
58
|
|
|
56
59
|
def __init__(
|
|
57
60
|
self,
|
|
@@ -62,12 +65,18 @@ class UniqueErrorWithParamsCode(UniqueError):
|
|
|
62
65
|
headers: dict[str, str] | None = None,
|
|
63
66
|
code: str | None = None,
|
|
64
67
|
original_error: Exception | str | None = None,
|
|
65
|
-
params: dict[str,
|
|
68
|
+
params: dict[str, Any] | str | None = None,
|
|
66
69
|
):
|
|
67
70
|
super().__init__(
|
|
68
|
-
message,
|
|
71
|
+
message,
|
|
72
|
+
http_body,
|
|
73
|
+
http_status,
|
|
74
|
+
json_body,
|
|
75
|
+
headers,
|
|
76
|
+
code,
|
|
77
|
+
original_error,
|
|
78
|
+
params,
|
|
69
79
|
)
|
|
70
|
-
self.params = params
|
|
71
80
|
|
|
72
81
|
def __repr__(self):
|
|
73
82
|
return "%s(message=%r, params=%r, code=%r, http_status=%r, request_id=%r)" % (
|
|
@@ -112,6 +121,10 @@ class PermissionError(UniqueError):
|
|
|
112
121
|
pass
|
|
113
122
|
|
|
114
123
|
|
|
124
|
+
class RateLimitError(APIError):
|
|
125
|
+
pass
|
|
126
|
+
|
|
127
|
+
|
|
115
128
|
class InvalidRequestError(UniqueErrorWithParamsCode):
|
|
116
129
|
def __init__(
|
|
117
130
|
self,
|
|
@@ -333,6 +333,35 @@ class class_method_variant(object):
|
|
|
333
333
|
return _wrapper
|
|
334
334
|
|
|
335
335
|
|
|
336
|
+
def _should_retry_error(
|
|
337
|
+
error: UniqueError,
|
|
338
|
+
error_messages: list[str],
|
|
339
|
+
should_retry_5xx: bool,
|
|
340
|
+
) -> bool:
|
|
341
|
+
status = error.http_status
|
|
342
|
+
if status is not None and 400 <= status < 500:
|
|
343
|
+
return False
|
|
344
|
+
if isinstance(error.params, Mapping) and error.params.get("retryable") is False:
|
|
345
|
+
return False
|
|
346
|
+
if should_retry_5xx and status is not None and 500 <= status < 600:
|
|
347
|
+
return True
|
|
348
|
+
return any(err_msg.lower() in str(error).lower() for err_msg in error_messages)
|
|
349
|
+
|
|
350
|
+
|
|
351
|
+
def _log_retry(error: UniqueError, attempt: int, max_retries: int) -> None:
|
|
352
|
+
# str(error) can carry upstream provider text via original_error.
|
|
353
|
+
params = error.params if isinstance(error.params, Mapping) else {}
|
|
354
|
+
logger.warning(
|
|
355
|
+
"Retrying Unique API call, attempt %d of %d: "
|
|
356
|
+
"code=%s http_status=%s correlation_id=%s",
|
|
357
|
+
attempt + 1,
|
|
358
|
+
max_retries,
|
|
359
|
+
error.code,
|
|
360
|
+
error.http_status,
|
|
361
|
+
params.get("correlationId"),
|
|
362
|
+
)
|
|
363
|
+
|
|
364
|
+
|
|
336
365
|
def retry_on_error(
|
|
337
366
|
error_messages: list[str],
|
|
338
367
|
max_retries: int = 3,
|
|
@@ -341,6 +370,13 @@ def retry_on_error(
|
|
|
341
370
|
error_class=APIError,
|
|
342
371
|
should_retry_5xx=False,
|
|
343
372
|
):
|
|
373
|
+
"""Retry ``APIError`` and ``APIConnectionError``.
|
|
374
|
+
|
|
375
|
+
4xx responses and errors with ``params.retryable`` false are not retried.
|
|
376
|
+
After the last attempt ``error_class`` is raised with the last error as
|
|
377
|
+
its ``__cause__``.
|
|
378
|
+
"""
|
|
379
|
+
|
|
344
380
|
def decorator(func: Callable[..., Any]) -> Callable[..., Any]:
|
|
345
381
|
@wraps(func)
|
|
346
382
|
async def async_wrapper(*args, **kwargs) -> Any:
|
|
@@ -350,25 +386,16 @@ def retry_on_error(
|
|
|
350
386
|
return await func(*args, **kwargs)
|
|
351
387
|
except (APIError, APIConnectionError) as e:
|
|
352
388
|
e = cast(UniqueError, e)
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
err_msg.lower() in str(e).lower() for err_msg in error_messages
|
|
356
|
-
)
|
|
357
|
-
# Add 5xx check if `should_retry_5xx` is True
|
|
358
|
-
has_valid_status = (
|
|
359
|
-
hasattr(e, "http_status") and e.http_status is not None
|
|
360
|
-
)
|
|
361
|
-
if should_retry_5xx and has_valid_status:
|
|
362
|
-
should_retry = should_retry or (
|
|
363
|
-
500 <= int(cast(int, e.http_status)) < 600
|
|
364
|
-
)
|
|
365
|
-
|
|
366
|
-
if not should_retry:
|
|
367
|
-
raise e # Raise the error if no retry condition is met
|
|
389
|
+
if not _should_retry_error(e, error_messages, should_retry_5xx):
|
|
390
|
+
raise
|
|
368
391
|
|
|
369
392
|
attempts += 1
|
|
370
393
|
if attempts >= max_retries:
|
|
371
|
-
raise error_class(
|
|
394
|
+
raise error_class(
|
|
395
|
+
f"Failed after {max_retries} attempts: {e}"
|
|
396
|
+
) from e
|
|
397
|
+
|
|
398
|
+
_log_retry(e, attempts, max_retries)
|
|
372
399
|
|
|
373
400
|
# Calculate exponential backoff with some randomness (jitter)
|
|
374
401
|
delay = initial_delay * (backoff_factor ** (attempts - 1))
|
|
@@ -382,25 +409,16 @@ def retry_on_error(
|
|
|
382
409
|
return func(*args, **kwargs)
|
|
383
410
|
except (APIError, APIConnectionError) as e:
|
|
384
411
|
e = cast(UniqueError, e)
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
err_msg.lower() in str(e).lower() for err_msg in error_messages
|
|
388
|
-
)
|
|
389
|
-
# Add 5xx check if `should_retry_5xx` is True
|
|
390
|
-
has_valid_status = (
|
|
391
|
-
hasattr(e, "http_status") and e.http_status is not None
|
|
392
|
-
)
|
|
393
|
-
if should_retry_5xx and has_valid_status:
|
|
394
|
-
should_retry = should_retry or (
|
|
395
|
-
500 <= int(cast(int, e.http_status)) < 600
|
|
396
|
-
)
|
|
397
|
-
|
|
398
|
-
if not should_retry:
|
|
399
|
-
raise e # Raise the error if no retry condition is met
|
|
412
|
+
if not _should_retry_error(e, error_messages, should_retry_5xx):
|
|
413
|
+
raise
|
|
400
414
|
|
|
401
415
|
attempts += 1
|
|
402
416
|
if attempts >= max_retries:
|
|
403
|
-
raise error_class(
|
|
417
|
+
raise error_class(
|
|
418
|
+
f"Failed after {max_retries} attempts: {e}"
|
|
419
|
+
) from e
|
|
420
|
+
|
|
421
|
+
_log_retry(e, attempts, max_retries)
|
|
404
422
|
|
|
405
423
|
# Calculate exponential backoff with some randomness (jitter)
|
|
406
424
|
delay = initial_delay * (backoff_factor ** (attempts - 1))
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/api_resources/__init__.py
RENAMED
|
File without changes
|
{unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/api_resources/_acronyms.py
RENAMED
|
File without changes
|
{unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/api_resources/_agentic_table.py
RENAMED
|
File without changes
|
|
File without changes
|
{unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/api_resources/_benchmarking.py
RENAMED
|
File without changes
|
{unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/api_resources/_briefing.py
RENAMED
|
File without changes
|
|
File without changes
|
{unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/api_resources/_content.py
RENAMED
|
File without changes
|
|
File without changes
|
{unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/api_resources/_elicitation.py
RENAMED
|
File without changes
|
{unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/api_resources/_embedding.py
RENAMED
|
File without changes
|
{unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/api_resources/_event.py
RENAMED
|
File without changes
|
{unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/api_resources/_folder.py
RENAMED
|
File without changes
|
{unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/api_resources/_group.py
RENAMED
|
File without changes
|
{unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/api_resources/_integrated.py
RENAMED
|
File without changes
|
{unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/api_resources/_llm_models.py
RENAMED
|
File without changes
|
|
File without changes
|
{unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/api_resources/_message.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/api_resources/_message_log.py
RENAMED
|
File without changes
|
{unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/api_resources/_message_tool.py
RENAMED
|
File without changes
|
{unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/api_resources/_module.py
RENAMED
|
File without changes
|
|
File without changes
|
{unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/api_resources/_search.py
RENAMED
|
File without changes
|
{unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/api_resources/_search_string.py
RENAMED
|
File without changes
|
|
File without changes
|
{unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/api_resources/_space.py
RENAMED
|
File without changes
|
|
File without changes
|
{unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/api_resources/_web_search.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/cli/commands/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/cli/commands/agentic_table.py
RENAMED
|
File without changes
|
|
File without changes
|
{unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/cli/commands/browser.py
RENAMED
|
File without changes
|
{unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/cli/commands/cite_file.py
RENAMED
|
File without changes
|
{unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/cli/commands/elicitation.py
RENAMED
|
File without changes
|
|
File without changes
|
{unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/cli/commands/folders.py
RENAMED
|
File without changes
|
|
File without changes
|
{unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/cli/commands/navigation.py
RENAMED
|
File without changes
|
|
File without changes
|
{unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/cli/commands/scheduled_tasks.py
RENAMED
|
File without changes
|
|
File without changes
|
{unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/cli/commands/subagent.py
RENAMED
|
File without changes
|
{unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/cli/commands/web_search.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/utils/analytics_order_run.py
RENAMED
|
File without changes
|
{unique_sdk-2026.44.0.dev14 → unique_sdk-2026.44.0.dev15}/unique_sdk/utils/benchmarking_run.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|