Skip to content

Commit 39622b3

Browse files
SDK regeneration
1 parent dcd81d8 commit 39622b3

13 files changed

Lines changed: 531 additions & 265 deletions

.fern/metadata.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
2-
"cliVersion": "4.48.0",
2+
"cliVersion": "4.60.0",
33
"generatorName": "fernapi/fern-python-sdk",
4-
"generatorVersion": "4.63.4",
4+
"generatorVersion": "5.2.1",
55
"generatorConfig": {
66
"pyproject_python_version": "^3.9",
77
"inline_request_params": false,
@@ -79,6 +79,6 @@
7979
}
8080
]
8181
},
82-
"originGitCommit": "40f3fd11b9fd6b445b024a2fcf6f2e67f6181147",
83-
"sdkVersion": "5.21.2"
82+
"originGitCommit": "6feada34ba0a2ce262d54edede0467ac6e99a5c9",
83+
"sdkVersion": "5.22.0"
8484
}

poetry.lock

Lines changed: 188 additions & 174 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ dynamic = ["version"]
44

55
[tool.poetry]
66
name = "cohere"
7-
version = "5.21.2"
7+
version = "5.22.0"
88
description = ""
99
readme = "README.md"
1010
authors = []
@@ -42,16 +42,16 @@ python = "^3.9"
4242
fastavro = "^1.9.4"
4343
httpx = ">=0.21.2"
4444
pydantic = ">= 1.9.2"
45-
pydantic-core = ">=2.18.2"
45+
pydantic-core = ">=2.18.2,<2.44.0"
4646
requests = "^2.0.0"
4747
tokenizers = ">=0.15,<1"
4848
types-requests = "^2.0.0"
4949
typing_extensions = ">= 4.0.0"
5050

5151
[tool.poetry.group.dev.dependencies]
5252
mypy = "==1.13.0"
53-
pytest = "^7.4.0"
54-
pytest-asyncio = "^0.23.5"
53+
pytest = "^8.2.0"
54+
pytest-asyncio = "^1.0.0"
5555
pytest-xdist = "^3.6.1"
5656
python-dateutil = "^2.9.0"
5757
types-python-dateutil = "^2.9.0.20240316"

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
fastavro==1.9.4
22
httpx>=0.21.2
33
pydantic>= 1.9.2
4-
pydantic-core>=2.18.2
4+
pydantic-core>=2.18.2,<2.44.0
55
requests==2.0.0
66
tokenizers>=0.15,<1
77
types-requests==2.0.0

src/cohere/base_client.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1604,6 +1604,9 @@ class AsyncBaseCohere:
16041604
headers : typing.Optional[typing.Dict[str, str]]
16051605
Additional headers to send with every request.
16061606
1607+
async_token : typing.Optional[typing.Callable[[], typing.Awaitable[str]]]
1608+
An async callable that returns a bearer token. Use this when token acquisition involves async I/O (e.g., refreshing tokens via an async HTTP client). When provided, this is used instead of the synchronous token for async requests.
1609+
16071610
timeout : typing.Optional[float]
16081611
The timeout to be used, in seconds, for requests. By default the timeout is 300 seconds, unless a custom httpx client is used, in which case this default is not enforced.
16091612
@@ -1634,6 +1637,7 @@ def __init__(
16341637
client_name: typing.Optional[str] = None,
16351638
token: typing.Optional[typing.Union[str, typing.Callable[[], str]]] = os.getenv("CO_API_KEY"),
16361639
headers: typing.Optional[typing.Dict[str, str]] = None,
1640+
async_token: typing.Optional[typing.Callable[[], typing.Awaitable[str]]] = None,
16371641
timeout: typing.Optional[float] = None,
16381642
follow_redirects: typing.Optional[bool] = True,
16391643
httpx_client: typing.Optional[httpx.AsyncClient] = None,
@@ -1649,6 +1653,7 @@ def __init__(
16491653
client_name=client_name,
16501654
token=token,
16511655
headers=headers,
1656+
async_token=async_token,
16521657
httpx_client=httpx_client
16531658
if httpx_client is not None
16541659
else httpx.AsyncClient(timeout=_defaulted_timeout, follow_redirects=follow_redirects)

src/cohere/batches/types/cancel_batch_response.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,6 @@
33
import typing
44

55
CancelBatchResponse = typing.Dict[str, typing.Any]
6+
"""
7+
Response to a request to cancel a batch.
8+
"""

src/cohere/core/client_wrapper.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,12 @@ def get_headers(self) -> typing.Dict[str, str]:
2929
import platform
3030

3131
headers: typing.Dict[str, str] = {
32-
"User-Agent": "cohere/5.21.2",
32+
"User-Agent": "cohere/5.22.0",
3333
"X-Fern-Language": "Python",
3434
"X-Fern-Runtime": f"python/{platform.python_version()}",
3535
"X-Fern-Platform": f"{platform.system().lower()}/{platform.release()}",
3636
"X-Fern-SDK-Name": "cohere",
37-
"X-Fern-SDK-Version": "5.21.2",
37+
"X-Fern-SDK-Version": "5.22.0",
3838
**(self.get_custom_headers() or {}),
3939
}
4040
if self._client_name is not None:

src/cohere/core/http_client.py

Lines changed: 86 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,12 @@ def _retry_timeout(response: httpx.Response, retries: int) -> float:
118118
return _add_symmetric_jitter(backoff)
119119

120120

121+
def _retry_timeout_from_retries(retries: int) -> float:
122+
"""Determine retry timeout using exponential backoff when no response is available."""
123+
backoff = min(INITIAL_RETRY_DELAY_SECONDS * pow(2.0, retries), MAX_RETRY_DELAY_SECONDS)
124+
return _add_symmetric_jitter(backoff)
125+
126+
121127
def _should_retry(response: httpx.Response) -> bool:
122128
retryable_400s = [429, 408, 409]
123129
return response.status_code >= 500 or response.status_code in retryable_400s
@@ -265,11 +271,13 @@ def __init__(
265271
base_timeout: typing.Callable[[], typing.Optional[float]],
266272
base_headers: typing.Callable[[], typing.Dict[str, str]],
267273
base_url: typing.Optional[typing.Callable[[], str]] = None,
274+
base_max_retries: int = 2,
268275
logging_config: typing.Optional[typing.Union[LogConfig, Logger]] = None,
269276
):
270277
self.base_url = base_url
271278
self.base_timeout = base_timeout
272279
self.base_headers = base_headers
280+
self.base_max_retries = base_max_retries
273281
self.httpx_client = httpx_client
274282
self.logger = create_logger(logging_config)
275283

@@ -364,19 +372,44 @@ def request(
364372
has_body=json_body is not None or data_body is not None,
365373
)
366374

367-
response = self.httpx_client.request(
368-
method=method,
369-
url=_request_url,
370-
headers=_request_headers,
371-
params=_encoded_params if _encoded_params else None,
372-
json=json_body,
373-
data=data_body,
374-
content=content,
375-
files=request_files,
376-
timeout=timeout,
375+
max_retries: int = (
376+
request_options.get("max_retries", self.base_max_retries)
377+
if request_options is not None
378+
else self.base_max_retries
377379
)
378380

379-
max_retries: int = request_options.get("max_retries", 2) if request_options is not None else 2
381+
try:
382+
response = self.httpx_client.request(
383+
method=method,
384+
url=_request_url,
385+
headers=_request_headers,
386+
params=_encoded_params if _encoded_params else None,
387+
json=json_body,
388+
data=data_body,
389+
content=content,
390+
files=request_files,
391+
timeout=timeout,
392+
)
393+
except (httpx.ConnectError, httpx.RemoteProtocolError):
394+
if retries < max_retries:
395+
time.sleep(_retry_timeout_from_retries(retries=retries))
396+
return self.request(
397+
path=path,
398+
method=method,
399+
base_url=base_url,
400+
params=params,
401+
json=json,
402+
data=data,
403+
content=content,
404+
files=files,
405+
headers=headers,
406+
request_options=request_options,
407+
retries=retries + 1,
408+
omit=omit,
409+
force_multipart=force_multipart,
410+
)
411+
raise
412+
380413
if _should_retry(response=response):
381414
if retries < max_retries:
382415
time.sleep(_retry_timeout(response=response, retries=retries))
@@ -386,12 +419,14 @@ def request(
386419
base_url=base_url,
387420
params=params,
388421
json=json,
422+
data=data,
389423
content=content,
390424
files=files,
391425
headers=headers,
392426
request_options=request_options,
393427
retries=retries + 1,
394428
omit=omit,
429+
force_multipart=force_multipart,
395430
)
396431

397432
if self.logger.is_debug():
@@ -518,12 +553,14 @@ def __init__(
518553
base_timeout: typing.Callable[[], typing.Optional[float]],
519554
base_headers: typing.Callable[[], typing.Dict[str, str]],
520555
base_url: typing.Optional[typing.Callable[[], str]] = None,
556+
base_max_retries: int = 2,
521557
async_base_headers: typing.Optional[typing.Callable[[], typing.Awaitable[typing.Dict[str, str]]]] = None,
522558
logging_config: typing.Optional[typing.Union[LogConfig, Logger]] = None,
523559
):
524560
self.base_url = base_url
525561
self.base_timeout = base_timeout
526562
self.base_headers = base_headers
563+
self.base_max_retries = base_max_retries
527564
self.async_base_headers = async_base_headers
528565
self.httpx_client = httpx_client
529566
self.logger = create_logger(logging_config)
@@ -627,19 +664,44 @@ async def request(
627664
has_body=json_body is not None or data_body is not None,
628665
)
629666

630-
response = await self.httpx_client.request(
631-
method=method,
632-
url=_request_url,
633-
headers=_request_headers,
634-
params=_encoded_params if _encoded_params else None,
635-
json=json_body,
636-
data=data_body,
637-
content=content,
638-
files=request_files,
639-
timeout=timeout,
667+
max_retries: int = (
668+
request_options.get("max_retries", self.base_max_retries)
669+
if request_options is not None
670+
else self.base_max_retries
640671
)
641672

642-
max_retries: int = request_options.get("max_retries", 2) if request_options is not None else 2
673+
try:
674+
response = await self.httpx_client.request(
675+
method=method,
676+
url=_request_url,
677+
headers=_request_headers,
678+
params=_encoded_params if _encoded_params else None,
679+
json=json_body,
680+
data=data_body,
681+
content=content,
682+
files=request_files,
683+
timeout=timeout,
684+
)
685+
except (httpx.ConnectError, httpx.RemoteProtocolError):
686+
if retries < max_retries:
687+
await asyncio.sleep(_retry_timeout_from_retries(retries=retries))
688+
return await self.request(
689+
path=path,
690+
method=method,
691+
base_url=base_url,
692+
params=params,
693+
json=json,
694+
data=data,
695+
content=content,
696+
files=files,
697+
headers=headers,
698+
request_options=request_options,
699+
retries=retries + 1,
700+
omit=omit,
701+
force_multipart=force_multipart,
702+
)
703+
raise
704+
643705
if _should_retry(response=response):
644706
if retries < max_retries:
645707
await asyncio.sleep(_retry_timeout(response=response, retries=retries))
@@ -649,12 +711,14 @@ async def request(
649711
base_url=base_url,
650712
params=params,
651713
json=json,
714+
data=data,
652715
content=content,
653716
files=files,
654717
headers=headers,
655718
request_options=request_options,
656719
retries=retries + 1,
657720
omit=omit,
721+
force_multipart=force_multipart,
658722
)
659723

660724
if self.logger.is_debug():

0 commit comments

Comments
 (0)