Skip to content

Commit fbda0e0

Browse files
SDK regeneration
1 parent 396b7d0 commit fbda0e0

74 files changed

Lines changed: 2603 additions & 3440 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

NOTICE.txt

Lines changed: 0 additions & 3024 deletions
This file was deleted.

reference.md

Lines changed: 136 additions & 109 deletions
Large diffs are not rendered by default.
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# This file was auto-generated by Fern from our API Definition.
2+
3+
import typing
4+
5+
import httpx
6+
7+
SDK_DEFAULT_TIMEOUT = 60
8+
9+
try:
10+
import httpx_aiohttp # type: ignore[import-not-found]
11+
except ImportError:
12+
13+
class DefaultAioHttpClient(httpx.AsyncClient): # type: ignore
14+
def __init__(self, **kwargs: typing.Any) -> None:
15+
raise RuntimeError(
16+
"To use the aiohttp client, install the aiohttp extra: pip install myorganization-python[aiohttp]"
17+
)
18+
19+
else:
20+
21+
class DefaultAioHttpClient(httpx_aiohttp.HttpxAiohttpClient): # type: ignore
22+
def __init__(self, **kwargs: typing.Any) -> None:
23+
kwargs.setdefault("timeout", SDK_DEFAULT_TIMEOUT)
24+
kwargs.setdefault("follow_redirects", True)
25+
super().__init__(**kwargs)
26+
27+
28+
class DefaultAsyncHttpxClient(httpx.AsyncClient):
29+
def __init__(self, **kwargs: typing.Any) -> None:
30+
kwargs.setdefault("timeout", SDK_DEFAULT_TIMEOUT)
31+
kwargs.setdefault("follow_redirects", True)
32+
super().__init__(**kwargs)

src/auth0/myorganization/client.py

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,24 @@ def organization(self):
111111
return self._organization
112112

113113

114+
def _make_default_async_client(
115+
timeout: typing.Optional[float],
116+
follow_redirects: typing.Optional[bool],
117+
) -> httpx.AsyncClient:
118+
try:
119+
import httpx_aiohttp # type: ignore[import-not-found]
120+
except ImportError:
121+
pass
122+
else:
123+
if follow_redirects is not None:
124+
return httpx_aiohttp.HttpxAiohttpClient(timeout=timeout, follow_redirects=follow_redirects)
125+
return httpx_aiohttp.HttpxAiohttpClient(timeout=timeout)
126+
127+
if follow_redirects is not None:
128+
return httpx.AsyncClient(timeout=timeout, follow_redirects=follow_redirects)
129+
return httpx.AsyncClient(timeout=timeout)
130+
131+
114132
class AsyncAuth0:
115133
"""
116134
Use this class to access the different functions within the SDK. You can instantiate any number of clients with different configuration that will propagate to these functions.
@@ -136,6 +154,9 @@ class AsyncAuth0:
136154
headers : typing.Optional[typing.Dict[str, str]]
137155
Additional headers to send with every request.
138156
157+
async_token : typing.Optional[typing.Callable[[], typing.Awaitable[str]]]
158+
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.
159+
139160
timeout : typing.Optional[float]
140161
The timeout to be used, in seconds, for requests. By default the timeout is 60 seconds, unless a custom httpx client is used, in which case this default is not enforced.
141162
@@ -165,6 +186,7 @@ def __init__(
165186
tenant_domain: typing.Optional[str] = None,
166187
token: typing.Union[str, typing.Callable[[], str]],
167188
headers: typing.Optional[typing.Dict[str, str]] = None,
189+
async_token: typing.Optional[typing.Callable[[], typing.Awaitable[str]]] = None,
168190
timeout: typing.Optional[float] = None,
169191
follow_redirects: typing.Optional[bool] = True,
170192
httpx_client: typing.Optional[httpx.AsyncClient] = None,
@@ -180,11 +202,10 @@ def __init__(
180202
base_url=_get_base_url(base_url=base_url, environment=environment),
181203
token=token,
182204
headers=headers,
205+
async_token=async_token,
183206
httpx_client=httpx_client
184207
if httpx_client is not None
185-
else httpx.AsyncClient(timeout=_defaulted_timeout, follow_redirects=follow_redirects)
186-
if follow_redirects is not None
187-
else httpx.AsyncClient(timeout=_defaulted_timeout),
208+
else _make_default_async_client(timeout=_defaulted_timeout, follow_redirects=follow_redirects),
188209
timeout=_defaulted_timeout,
189210
logging=logging,
190211
)

src/auth0/myorganization/core/__init__.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,14 @@
88
if typing.TYPE_CHECKING:
99
from .api_error import ApiError
1010
from .client_wrapper import AsyncClientWrapper, BaseClientWrapper, SyncClientWrapper
11-
from .datetime_utils import serialize_datetime
11+
from .datetime_utils import Rfc2822DateTime, parse_rfc2822_datetime, serialize_datetime
1212
from .file import File, convert_file_dict_to_httpx_tuples, with_content_type
1313
from .http_client import AsyncHttpClient, HttpClient
1414
from .http_response import AsyncHttpResponse, HttpResponse
1515
from .jsonable_encoder import jsonable_encoder
1616
from .logging import ConsoleLogger, ILogger, LogConfig, LogLevel, Logger, create_logger
17+
from .pagination import AsyncPager, SyncPager
18+
from .parse_error import ParsingError
1719
from .pydantic_utilities import (
1820
IS_PYDANTIC_V2,
1921
UniversalBaseModel,
@@ -32,6 +34,7 @@
3234
"AsyncClientWrapper": ".client_wrapper",
3335
"AsyncHttpClient": ".http_client",
3436
"AsyncHttpResponse": ".http_response",
37+
"AsyncPager": ".pagination",
3538
"BaseClientWrapper": ".client_wrapper",
3639
"ConsoleLogger": ".logging",
3740
"FieldMetadata": ".serialization",
@@ -43,8 +46,11 @@
4346
"LogConfig": ".logging",
4447
"LogLevel": ".logging",
4548
"Logger": ".logging",
49+
"ParsingError": ".parse_error",
4650
"RequestOptions": ".request_options",
51+
"Rfc2822DateTime": ".datetime_utils",
4752
"SyncClientWrapper": ".client_wrapper",
53+
"SyncPager": ".pagination",
4854
"UniversalBaseModel": ".pydantic_utilities",
4955
"UniversalRootModel": ".pydantic_utilities",
5056
"convert_and_respect_annotation_metadata": ".serialization",
@@ -53,6 +59,7 @@
5359
"encode_query": ".query_encoder",
5460
"jsonable_encoder": ".jsonable_encoder",
5561
"parse_obj_as": ".pydantic_utilities",
62+
"parse_rfc2822_datetime": ".datetime_utils",
5663
"remove_none_from_dict": ".remove_none_from_dict",
5764
"serialize_datetime": ".datetime_utils",
5865
"universal_field_validator": ".pydantic_utilities",
@@ -88,6 +95,7 @@ def __dir__():
8895
"AsyncClientWrapper",
8996
"AsyncHttpClient",
9097
"AsyncHttpResponse",
98+
"AsyncPager",
9199
"BaseClientWrapper",
92100
"ConsoleLogger",
93101
"FieldMetadata",
@@ -99,8 +107,11 @@ def __dir__():
99107
"LogConfig",
100108
"LogLevel",
101109
"Logger",
110+
"ParsingError",
102111
"RequestOptions",
112+
"Rfc2822DateTime",
103113
"SyncClientWrapper",
114+
"SyncPager",
104115
"UniversalBaseModel",
105116
"UniversalRootModel",
106117
"convert_and_respect_annotation_metadata",
@@ -109,6 +120,7 @@ def __dir__():
109120
"encode_query",
110121
"jsonable_encoder",
111122
"parse_obj_as",
123+
"parse_rfc2822_datetime",
112124
"remove_none_from_dict",
113125
"serialize_datetime",
114126
"universal_field_validator",

src/auth0/myorganization/core/datetime_utils.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,48 @@
11
# This file was auto-generated by Fern from our API Definition.
22

33
import datetime as dt
4+
from email.utils import parsedate_to_datetime
5+
from typing import Any
6+
7+
import pydantic
8+
9+
IS_PYDANTIC_V2 = pydantic.VERSION.startswith("2.")
10+
11+
12+
def parse_rfc2822_datetime(v: Any) -> dt.datetime:
13+
"""
14+
Parse an RFC 2822 datetime string (e.g., "Wed, 02 Oct 2002 13:00:00 GMT")
15+
into a datetime object. If the value is already a datetime, return it as-is.
16+
Falls back to ISO 8601 parsing if RFC 2822 parsing fails.
17+
"""
18+
if isinstance(v, dt.datetime):
19+
return v
20+
if isinstance(v, str):
21+
try:
22+
return parsedate_to_datetime(v)
23+
except Exception:
24+
pass
25+
# Fallback to ISO 8601 parsing
26+
return dt.datetime.fromisoformat(v.replace("Z", "+00:00"))
27+
raise ValueError(f"Expected str or datetime, got {type(v)}")
28+
29+
30+
class Rfc2822DateTime(dt.datetime):
31+
"""A datetime subclass that parses RFC 2822 date strings.
32+
33+
On Pydantic V1, uses __get_validators__ for pre-validation.
34+
On Pydantic V2, uses __get_pydantic_core_schema__ for BeforeValidator-style parsing.
35+
"""
36+
37+
@classmethod
38+
def __get_validators__(cls): # type: ignore[no-untyped-def]
39+
yield parse_rfc2822_datetime
40+
41+
@classmethod
42+
def __get_pydantic_core_schema__(cls, _source_type: Any, _handler: Any) -> Any: # type: ignore[override]
43+
from pydantic_core import core_schema
44+
45+
return core_schema.no_info_before_validator_function(parse_rfc2822_datetime, core_schema.datetime_schema())
446

547

648
def serialize_datetime(v: dt.datetime) -> str:

src/auth0/myorganization/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)