isaacus 0.3.1__py3-none-any.whl → 0.3.3__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.
isaacus/_base_client.py CHANGED
@@ -409,7 +409,8 @@ class BaseClient(Generic[_HttpxClientT, _DefaultStreamT]):
409
409
 
410
410
  idempotency_header = self._idempotency_header
411
411
  if idempotency_header and options.method.lower() != "get" and idempotency_header not in headers:
412
- headers[idempotency_header] = options.idempotency_key or self._idempotency_key()
412
+ options.idempotency_key = options.idempotency_key or self._idempotency_key()
413
+ headers[idempotency_header] = options.idempotency_key
413
414
 
414
415
  # Don't set these headers if they were already set or removed by the caller. We check
415
416
  # `custom_headers`, which can contain `Omit()`, instead of `headers` to account for the removal case.
@@ -943,6 +944,10 @@ class SyncAPIClient(BaseClient[httpx.Client, Stream[Any]]):
943
944
  request = self._build_request(options, retries_taken=retries_taken)
944
945
  self._prepare_request(request)
945
946
 
947
+ if options.idempotency_key:
948
+ # ensure the idempotency key is reused between requests
949
+ input_options.idempotency_key = options.idempotency_key
950
+
946
951
  kwargs: HttpxSendArgs = {}
947
952
  if self.custom_auth is not None:
948
953
  kwargs["auth"] = self.custom_auth
@@ -1475,6 +1480,10 @@ class AsyncAPIClient(BaseClient[httpx.AsyncClient, AsyncStream[Any]]):
1475
1480
  request = self._build_request(options, retries_taken=retries_taken)
1476
1481
  await self._prepare_request(request)
1477
1482
 
1483
+ if options.idempotency_key:
1484
+ # ensure the idempotency key is reused between requests
1485
+ input_options.idempotency_key = options.idempotency_key
1486
+
1478
1487
  kwargs: HttpxSendArgs = {}
1479
1488
  if self.custom_auth is not None:
1480
1489
  kwargs["auth"] = self.custom_auth
@@ -5,13 +5,15 @@ import base64
5
5
  import pathlib
6
6
  from typing import Any, Mapping, TypeVar, cast
7
7
  from datetime import date, datetime
8
- from typing_extensions import Literal, get_args, override, get_type_hints
8
+ from typing_extensions import Literal, get_args, override, get_type_hints as _get_type_hints
9
9
 
10
10
  import anyio
11
11
  import pydantic
12
12
 
13
13
  from ._utils import (
14
14
  is_list,
15
+ is_given,
16
+ lru_cache,
15
17
  is_mapping,
16
18
  is_iterable,
17
19
  )
@@ -108,6 +110,7 @@ def transform(
108
110
  return cast(_T, transformed)
109
111
 
110
112
 
113
+ @lru_cache(maxsize=8096)
111
114
  def _get_annotated_type(type_: type) -> type | None:
112
115
  """If the given type is an `Annotated` type then it is returned, if not `None` is returned.
113
116
 
@@ -142,6 +145,10 @@ def _maybe_transform_key(key: str, type_: type) -> str:
142
145
  return key
143
146
 
144
147
 
148
+ def _no_transform_needed(annotation: type) -> bool:
149
+ return annotation == float or annotation == int
150
+
151
+
145
152
  def _transform_recursive(
146
153
  data: object,
147
154
  *,
@@ -184,6 +191,15 @@ def _transform_recursive(
184
191
  return cast(object, data)
185
192
 
186
193
  inner_type = extract_type_arg(stripped_type, 0)
194
+ if _no_transform_needed(inner_type):
195
+ # for some types there is no need to transform anything, so we can get a small
196
+ # perf boost from skipping that work.
197
+ #
198
+ # but we still need to convert to a list to ensure the data is json-serializable
199
+ if is_list(data):
200
+ return data
201
+ return list(data)
202
+
187
203
  return [_transform_recursive(d, annotation=annotation, inner_type=inner_type) for d in data]
188
204
 
189
205
  if is_union_type(stripped_type):
@@ -245,6 +261,11 @@ def _transform_typeddict(
245
261
  result: dict[str, object] = {}
246
262
  annotations = get_type_hints(expected_type, include_extras=True)
247
263
  for key, value in data.items():
264
+ if not is_given(value):
265
+ # we don't need to include `NotGiven` values here as they'll
266
+ # be stripped out before the request is sent anyway
267
+ continue
268
+
248
269
  type_ = annotations.get(key)
249
270
  if type_ is None:
250
271
  # we do not have a type annotation for this field, leave it as is
@@ -332,6 +353,15 @@ async def _async_transform_recursive(
332
353
  return cast(object, data)
333
354
 
334
355
  inner_type = extract_type_arg(stripped_type, 0)
356
+ if _no_transform_needed(inner_type):
357
+ # for some types there is no need to transform anything, so we can get a small
358
+ # perf boost from skipping that work.
359
+ #
360
+ # but we still need to convert to a list to ensure the data is json-serializable
361
+ if is_list(data):
362
+ return data
363
+ return list(data)
364
+
335
365
  return [await _async_transform_recursive(d, annotation=annotation, inner_type=inner_type) for d in data]
336
366
 
337
367
  if is_union_type(stripped_type):
@@ -393,6 +423,11 @@ async def _async_transform_typeddict(
393
423
  result: dict[str, object] = {}
394
424
  annotations = get_type_hints(expected_type, include_extras=True)
395
425
  for key, value in data.items():
426
+ if not is_given(value):
427
+ # we don't need to include `NotGiven` values here as they'll
428
+ # be stripped out before the request is sent anyway
429
+ continue
430
+
396
431
  type_ = annotations.get(key)
397
432
  if type_ is None:
398
433
  # we do not have a type annotation for this field, leave it as is
@@ -400,3 +435,13 @@ async def _async_transform_typeddict(
400
435
  else:
401
436
  result[_maybe_transform_key(key, type_)] = await _async_transform_recursive(value, annotation=type_)
402
437
  return result
438
+
439
+
440
+ @lru_cache(maxsize=8096)
441
+ def get_type_hints(
442
+ obj: Any,
443
+ globalns: dict[str, Any] | None = None,
444
+ localns: Mapping[str, Any] | None = None,
445
+ include_extras: bool = False,
446
+ ) -> dict[str, Any]:
447
+ return _get_type_hints(obj, globalns=globalns, localns=localns, include_extras=include_extras)
isaacus/_utils/_typing.py CHANGED
@@ -13,6 +13,7 @@ from typing_extensions import (
13
13
  get_origin,
14
14
  )
15
15
 
16
+ from ._utils import lru_cache
16
17
  from .._types import InheritsGeneric
17
18
  from .._compat import is_union as _is_union
18
19
 
@@ -66,6 +67,7 @@ def is_type_alias_type(tp: Any, /) -> TypeIs[typing_extensions.TypeAliasType]:
66
67
 
67
68
 
68
69
  # Extracts T from Annotated[T, ...] or from Required[Annotated[T, ...]]
70
+ @lru_cache(maxsize=8096)
69
71
  def strip_annotated_type(typ: type) -> type:
70
72
  if is_required_type(typ) or is_annotated_type(typ):
71
73
  return strip_annotated_type(cast(type, get_args(typ)[0]))
isaacus/_version.py CHANGED
@@ -1,4 +1,4 @@
1
1
  # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
2
 
3
3
  __title__ = "isaacus"
4
- __version__ = "0.3.1" # x-release-please-version
4
+ __version__ = "0.3.3" # x-release-please-version
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: isaacus
3
- Version: 0.3.1
3
+ Version: 0.3.3
4
4
  Summary: The official Python library for the isaacus API
5
5
  Project-URL: Homepage, https://github.com/isaacus-dev/isaacus-python
6
6
  Project-URL: Repository, https://github.com/isaacus-dev/isaacus-python
@@ -1,5 +1,5 @@
1
1
  isaacus/__init__.py,sha256=Wgs-qjblN9tJvI22iWwi5CfiVvyn1drBPnTYhVj7cWk,2426
2
- isaacus/_base_client.py,sha256=ORZD1WjSTLicI9Bv0nJdIF7OGDv0Wl4ySK0ygQ9AjM8,64958
2
+ isaacus/_base_client.py,sha256=-vFveHvk1CTWaJzq66vjAg5bPOqSuZsMyYgrnZMrsh0,65366
3
3
  isaacus/_client.py,sha256=aqn4G8onxd-CBS_Tgnr9QA41g6ltcIScHsuUo9U1JeU,15874
4
4
  isaacus/_compat.py,sha256=VWemUKbj6DDkQ-O4baSpHVLJafotzeXmCQGJugfVTIw,6580
5
5
  isaacus/_constants.py,sha256=S14PFzyN9-I31wiV7SmIlL5Ga0MLHxdvegInGdXH7tM,462
@@ -11,7 +11,7 @@ isaacus/_resource.py,sha256=iP_oYhz5enCI58mK7hlwLoPMPh4Q5s8-KBv-jGfv2aM,1106
11
11
  isaacus/_response.py,sha256=5v-mAgiP6X9EBGBvTYVdwuDjikiha-dc1dYmadIraCU,28795
12
12
  isaacus/_streaming.py,sha256=tMBfwrfEFWm0v7vWFgjn_lizsoD70lPkYigIBuADaCM,10104
13
13
  isaacus/_types.py,sha256=WCRAb8jikEJoOi8nza8l5NnOTKgZlpmN5fkiHoKoY08,6144
14
- isaacus/_version.py,sha256=SER2ceDbCOArLjY72wT36LvgLC2O_7JZhVGhu6jm474,159
14
+ isaacus/_version.py,sha256=e-M1q910IdIbw8sz6m5Ry2saoH5ROSo7HtHKq4fW4JI,159
15
15
  isaacus/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
16
  isaacus/_utils/__init__.py,sha256=PNZ_QJuzZEgyYXqkO1HVhGkj5IU9bglVUcw7H-Knjzw,2062
17
17
  isaacus/_utils/_logs.py,sha256=rwa1Yzjbs2JaFn9KQ06rH5c_GSNa--BVwWnWhvvT1tY,777
@@ -19,8 +19,8 @@ isaacus/_utils/_proxy.py,sha256=z3zsateHtb0EARTWKk8QZNHfPkqJbqwd1lM993LBwGE,1902
19
19
  isaacus/_utils/_reflection.py,sha256=ZmGkIgT_PuwedyNBrrKGbxoWtkpytJNU1uU4QHnmEMU,1364
20
20
  isaacus/_utils/_streams.py,sha256=SMC90diFFecpEg_zgDRVbdR3hSEIgVVij4taD-noMLM,289
21
21
  isaacus/_utils/_sync.py,sha256=TpGLrrhRNWTJtODNE6Fup3_k7zrWm1j2RlirzBwre-0,2862
22
- isaacus/_utils/_transform.py,sha256=asrbdx4Pf5NupzaB8QdEjypW_DgHjjkpswHT0Jum4S0,13987
23
- isaacus/_utils/_typing.py,sha256=nTJz0jcrQbEgxwy4TtAkNxuU0QHHlmc6mQtA6vIR8tg,4501
22
+ isaacus/_utils/_transform.py,sha256=n7kskEWz6o__aoNvhFoGVyDoalNe6mJwp-g7BWkdj88,15617
23
+ isaacus/_utils/_typing.py,sha256=nOFiIH5faG-h5Ha-Ky2aZxw5kmR6iX8KzNtsn3JEWoA,4556
24
24
  isaacus/_utils/_utils.py,sha256=8UmbPOy_AAr2uUjjFui-VZSrVBHRj6bfNEKRp5YZP2A,12004
25
25
  isaacus/lib/.keep,sha256=wuNrz-5SXo3jJaJOJgz4vFHM41YH_g20F5cRQo0vLes,224
26
26
  isaacus/resources/__init__.py,sha256=N582fDHPnidiDhuxYlHKV_Io6WDNMI3HE8Yze3l8wqU,1171
@@ -34,7 +34,7 @@ isaacus/types/reranking_create_params.py,sha256=qJlXHbt4CxlBmdDpmqLC_VJ9ldTHBy4k
34
34
  isaacus/types/classifications/__init__.py,sha256=GX6WFRzjx9qcuJhdRZjFLJRYMM4d5J8F5N-BUq4ZgP0,296
35
35
  isaacus/types/classifications/universal_classification.py,sha256=Dmh03lcEzb5atmmdhNs99kPX9HQ1B_BaNKUojxu2nlA,1654
36
36
  isaacus/types/classifications/universal_create_params.py,sha256=fFhx7SfLPA36lwCYPEzrW2jr7hFlSFyVPqBzNcHXQ2w,2259
37
- isaacus-0.3.1.dist-info/METADATA,sha256=SFCWb7EcRoCYN-L6-wkUiRjm4EzTcm_orMwcZRpf-0g,14296
38
- isaacus-0.3.1.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
39
- isaacus-0.3.1.dist-info/licenses/LICENSE,sha256=lUen4LYVFVGEVXBsntBAPsQsOWgMkno1e9WfgWkpZ-k,11337
40
- isaacus-0.3.1.dist-info/RECORD,,
37
+ isaacus-0.3.3.dist-info/METADATA,sha256=XJxWwrEkfc7Ig22POMnX2qrpb-_57WLPNsPMfxjN9gg,14296
38
+ isaacus-0.3.3.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
39
+ isaacus-0.3.3.dist-info/licenses/LICENSE,sha256=lUen4LYVFVGEVXBsntBAPsQsOWgMkno1e9WfgWkpZ-k,11337
40
+ isaacus-0.3.3.dist-info/RECORD,,