unique_sdk 0.9.7__tar.gz → 0.9.9__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.
Files changed (36) hide show
  1. {unique_sdk-0.9.7 → unique_sdk-0.9.9}/CHANGELOG.md +6 -0
  2. {unique_sdk-0.9.7 → unique_sdk-0.9.9}/PKG-INFO +9 -3
  3. {unique_sdk-0.9.7 → unique_sdk-0.9.9}/pyproject.toml +4 -2
  4. {unique_sdk-0.9.7 → unique_sdk-0.9.9}/unique_sdk/_api_resource.py +13 -1
  5. {unique_sdk-0.9.7 → unique_sdk-0.9.9}/unique_sdk/_util.py +65 -4
  6. unique_sdk-0.9.9/unique_sdk/_version.py +1 -0
  7. {unique_sdk-0.9.7 → unique_sdk-0.9.9}/unique_sdk/api_resources/_message.py +15 -0
  8. unique_sdk-0.9.7/unique_sdk/_version.py +0 -1
  9. {unique_sdk-0.9.7 → unique_sdk-0.9.9}/LICENSE +0 -0
  10. {unique_sdk-0.9.7 → unique_sdk-0.9.9}/README.md +0 -0
  11. {unique_sdk-0.9.7 → unique_sdk-0.9.9}/unique_sdk/__init__.py +0 -0
  12. {unique_sdk-0.9.7 → unique_sdk-0.9.9}/unique_sdk/_api_requestor.py +0 -0
  13. {unique_sdk-0.9.7 → unique_sdk-0.9.9}/unique_sdk/_api_version.py +0 -0
  14. {unique_sdk-0.9.7 → unique_sdk-0.9.9}/unique_sdk/_error.py +0 -0
  15. {unique_sdk-0.9.7 → unique_sdk-0.9.9}/unique_sdk/_http_client.py +0 -0
  16. {unique_sdk-0.9.7 → unique_sdk-0.9.9}/unique_sdk/_list_object.py +0 -0
  17. {unique_sdk-0.9.7 → unique_sdk-0.9.9}/unique_sdk/_object_classes.py +0 -0
  18. {unique_sdk-0.9.7 → unique_sdk-0.9.9}/unique_sdk/_request_options.py +0 -0
  19. {unique_sdk-0.9.7 → unique_sdk-0.9.9}/unique_sdk/_unique_object.py +0 -0
  20. {unique_sdk-0.9.7 → unique_sdk-0.9.9}/unique_sdk/_unique_ql.py +0 -0
  21. {unique_sdk-0.9.7 → unique_sdk-0.9.9}/unique_sdk/_unique_response.py +0 -0
  22. {unique_sdk-0.9.7 → unique_sdk-0.9.9}/unique_sdk/_webhook.py +0 -0
  23. {unique_sdk-0.9.7 → unique_sdk-0.9.9}/unique_sdk/api_resources/__init__.py +0 -0
  24. {unique_sdk-0.9.7 → unique_sdk-0.9.9}/unique_sdk/api_resources/_acronyms.py +0 -0
  25. {unique_sdk-0.9.7 → unique_sdk-0.9.9}/unique_sdk/api_resources/_chat_completion.py +0 -0
  26. {unique_sdk-0.9.7 → unique_sdk-0.9.9}/unique_sdk/api_resources/_content.py +0 -0
  27. {unique_sdk-0.9.7 → unique_sdk-0.9.9}/unique_sdk/api_resources/_embedding.py +0 -0
  28. {unique_sdk-0.9.7 → unique_sdk-0.9.9}/unique_sdk/api_resources/_event.py +0 -0
  29. {unique_sdk-0.9.7 → unique_sdk-0.9.9}/unique_sdk/api_resources/_integrated.py +0 -0
  30. {unique_sdk-0.9.7 → unique_sdk-0.9.9}/unique_sdk/api_resources/_search.py +0 -0
  31. {unique_sdk-0.9.7 → unique_sdk-0.9.9}/unique_sdk/api_resources/_search_string.py +0 -0
  32. {unique_sdk-0.9.7 → unique_sdk-0.9.9}/unique_sdk/api_resources/_short_term_memory.py +0 -0
  33. {unique_sdk-0.9.7 → unique_sdk-0.9.9}/unique_sdk/utils/chat_history.py +0 -0
  34. {unique_sdk-0.9.7 → unique_sdk-0.9.9}/unique_sdk/utils/file_io.py +0 -0
  35. {unique_sdk-0.9.7 → unique_sdk-0.9.9}/unique_sdk/utils/sources.py +0 -0
  36. {unique_sdk-0.9.7 → unique_sdk-0.9.9}/unique_sdk/utils/token.py +0 -0
@@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.9.9] - 2024-10-23
9
+ - Revert deletion of `Message.retrieve` method
10
+
11
+ ## [0.9.8] - 2024-10-16
12
+ - Add `retries` for `_static_request` and `_static_request_async` in `APIResource` - When the error messages contains either `"problem proxying the request"`,
13
+ or `"Upstream service reached a hard timeout"`,
8
14
  ## [0.9.7] - 2024-09-23
9
15
  - Add `completedAt` to `CreateParams` of `Message`
10
16
 
@@ -1,10 +1,10 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: unique_sdk
3
- Version: 0.9.7
3
+ Version: 0.9.9
4
4
  Summary:
5
5
  License: MIT
6
- Author: Konstantin Krauss
7
- Author-email: konstantin@unique.ch
6
+ Author: Martin Fadler
7
+ Author-email: martin.fadler@unique.ch
8
8
  Requires-Python: >=3.11,<4.0
9
9
  Classifier: License :: OSI Approved :: MIT License
10
10
  Classifier: Programming Language :: Python :: 3
@@ -894,6 +894,12 @@ All notable changes to this project will be documented in this file.
894
894
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
895
895
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
896
896
 
897
+ ## [0.9.9] - 2024-10-23
898
+ - Revert deletion of `Message.retrieve` method
899
+
900
+ ## [0.9.8] - 2024-10-16
901
+ - Add `retries` for `_static_request` and `_static_request_async` in `APIResource` - When the error messages contains either `"problem proxying the request"`,
902
+ or `"Upstream service reached a hard timeout"`,
897
903
  ## [0.9.7] - 2024-09-23
898
904
  - Add `completedAt` to `CreateParams` of `Message`
899
905
 
@@ -1,8 +1,9 @@
1
1
  [tool.poetry]
2
2
  name = "unique_sdk"
3
- version = "0.9.7"
3
+ version = "0.9.9"
4
4
  description = ""
5
5
  authors = [
6
+ "Martin Fadler <martin.fadler@unique.ch>",
6
7
  "Konstantin Krauss <konstantin@unique.ch>",
7
8
  "Andreas Hauri <andreas@unique.ch>",
8
9
  ]
@@ -16,10 +17,11 @@ typing-extensions = "^4.9.0"
16
17
 
17
18
  [tool.poetry.group.dev.dependencies]
18
19
  ruff = "0.4.10"
19
- pytest = "^7.4.3"
20
+ pytest = "^8.0"
20
21
  tox = "^4.11.4"
21
22
  pyright = "^1.1.341"
22
23
  pytest-cov = "^4.1.0"
24
+ pytest-asyncio = "^0.24.0"
23
25
 
24
26
  [build-system]
25
27
  requires = ["poetry-core"]
@@ -14,10 +14,20 @@ from urllib.parse import quote_plus
14
14
  from unique_sdk._api_requestor import APIRequestor
15
15
  from unique_sdk._error import InvalidRequestError
16
16
  from unique_sdk._unique_object import UniqueObject
17
- from unique_sdk._util import convert_to_unique_object
17
+ from unique_sdk._util import convert_to_unique_object, retry_on_error
18
18
 
19
19
  T = TypeVar("T", bound=UniqueObject)
20
20
 
21
+ retry_dict = {
22
+ "error_messages": [
23
+ "problem proxying the request",
24
+ "Upstream service reached a hard timeout",
25
+ ],
26
+ "max_retries": 3,
27
+ "backoff_factor": 2,
28
+ "initial_delay": 1,
29
+ }
30
+
21
31
 
22
32
  class APIResource(UniqueObject, Generic[T]):
23
33
  OBJECT_NAME: ClassVar[str]
@@ -164,6 +174,7 @@ class APIResource(UniqueObject, Generic[T]):
164
174
  # The `method_` and `url_` arguments are suffixed with an underscore to
165
175
  # avoid conflicting with actual request parameters in `params`.
166
176
  @classmethod
177
+ @retry_on_error(**retry_dict)
167
178
  def _static_request(
168
179
  cls,
169
180
  method_,
@@ -182,6 +193,7 @@ class APIResource(UniqueObject, Generic[T]):
182
193
  # The `method_` and `url_` arguments are suffixed with an underscore to
183
194
  # avoid conflicting with actual request parameters in `params`.
184
195
  @classmethod
196
+ @retry_on_error(**retry_dict)
185
197
  async def _static_request_async(
186
198
  cls,
187
199
  method_,
@@ -1,13 +1,18 @@
1
+ import asyncio
1
2
  import functools
2
3
  import logging
3
4
  import os
5
+ import random
4
6
  import re
5
7
  import sys
6
- from typing import Any, Dict, List, Optional, TypeVar, Union, cast, overload
8
+ import time
9
+ from functools import wraps
10
+ from typing import Any, Callable, Dict, List, Optional, TypeVar, Union, cast, overload
7
11
 
8
12
  from typing_extensions import TYPE_CHECKING, Type
9
13
 
10
14
  import unique_sdk # noqa: F401
15
+ from unique_sdk._error import APIError
11
16
 
12
17
  if TYPE_CHECKING:
13
18
  from unique_sdk._unique_object import UniqueObject
@@ -21,10 +26,9 @@ logger: logging.Logger = logging.getLogger("unique")
21
26
  def _console_log_level():
22
27
  if unique_sdk.log in ["debug", "info"]:
23
28
  return unique_sdk.log
24
- elif UNIQUE_LOG in ["debug", "info"]:
29
+ if UNIQUE_LOG in ["debug", "info"]:
25
30
  return UNIQUE_LOG
26
- else:
27
- return None
31
+ return None
28
32
 
29
33
 
30
34
  def log_debug(message, **params):
@@ -188,3 +192,60 @@ class class_method_variant(object):
188
192
  return class_method(*args, **kwargs)
189
193
 
190
194
  return _wrapper
195
+
196
+
197
+ def retry_on_error(
198
+ error_messages: List[str],
199
+ max_retries: int = 3,
200
+ initial_delay: int = 1,
201
+ backoff_factor: int = 2,
202
+ error_class=APIError,
203
+ ):
204
+ def decorator(func: Callable) -> Callable:
205
+ @wraps(func)
206
+ async def async_wrapper(*args, **kwargs) -> Any:
207
+ attempts = 0
208
+ while attempts < max_retries:
209
+ try:
210
+ return await func(*args, **kwargs)
211
+ except Exception as e:
212
+ if not any(
213
+ err_msg.lower() in str(e).lower() for err_msg in error_messages
214
+ ):
215
+ raise e # Raise the error if none of the messages match
216
+
217
+ attempts += 1
218
+ if attempts >= max_retries:
219
+ raise error_class(f"Failed after {max_retries} attempts: {e}")
220
+
221
+ # Calculate exponential backoff with some randomness (jitter)
222
+ delay = initial_delay * (backoff_factor ** (attempts - 1))
223
+ jitter = random.uniform(0, 0.1 * delay)
224
+ await asyncio.sleep(delay + jitter)
225
+
226
+ def sync_wrapper(*args, **kwargs) -> Any:
227
+ attempts = 0
228
+ while attempts < max_retries:
229
+ try:
230
+ return func(*args, **kwargs)
231
+ except Exception as e:
232
+ if not any(
233
+ err_msg.lower() in str(e).lower() for err_msg in error_messages
234
+ ):
235
+ raise e # Raise the error if none of the messages match
236
+
237
+ attempts += 1
238
+ if attempts >= max_retries:
239
+ raise error_class(f"Failed after {max_retries} attempts: {e}")
240
+
241
+ # Calculate exponential backoff with some randomness (jitter)
242
+ delay = initial_delay * (backoff_factor ** (attempts - 1))
243
+ jitter = random.uniform(0, 0.1 * delay)
244
+ time.sleep(delay + jitter)
245
+
246
+ # Return the appropriate wrapper based on whether the function is async
247
+ if asyncio.iscoroutinefunction(func):
248
+ return async_wrapper
249
+ return sync_wrapper
250
+
251
+ return decorator
@@ -0,0 +1 @@
1
+ VERSION = "0.9.8"
@@ -115,6 +115,21 @@ class Message(APIResource["Message"]):
115
115
 
116
116
  return result
117
117
 
118
+ @classmethod
119
+ def retrieve(
120
+ cls,
121
+ user_id: str,
122
+ company_id: str,
123
+ id: str,
124
+ **params: Unpack["Message.RetrieveParams"],
125
+ ) -> "Message":
126
+ """
127
+ Retrieves a Message object.
128
+ """
129
+ instance = cls(user_id, company_id, id, **params)
130
+ instance.refresh(user_id, company_id)
131
+ return instance
132
+
118
133
  @classmethod
119
134
  async def retrieve_async(
120
135
  cls,
@@ -1 +0,0 @@
1
- VERSION = "0.9.7"
File without changes
File without changes