diff --git a/HISTORY.md b/HISTORY.md index 3e1bc15f76..819eaca8f0 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -10,6 +10,11 @@ Release History **Added** - Oriented-object headers. Access them through the new property `oheaders` in your `Response`. +- Propagated the argument `retries` in `niquests.api` for all functions. +- Added argument `retries` in the `Session` constructor. + +**Fixed** +- No configured retry of your HTTP requests but getting exception `MaxRetryError` nonetheless. 3.0.0b0 (2023-09-21) ------------------- diff --git a/src/niquests/_constant.py b/src/niquests/_constant.py index a3cc2f2887..74c96272a1 100644 --- a/src/niquests/_constant.py +++ b/src/niquests/_constant.py @@ -1,6 +1,6 @@ import wassima -from ._typing import TimeoutType +from ._typing import RetryType, TimeoutType #: Default timeout (total) assigned for GET, HEAD, and OPTIONS methods. READ_DEFAULT_TIMEOUT: TimeoutType = 30 @@ -9,6 +9,6 @@ DEFAULT_POOLBLOCK: bool = False DEFAULT_POOLSIZE: int = 10 -DEFAULT_RETRIES: int = 0 +DEFAULT_RETRIES: RetryType = False DEFAULT_CA_BUNDLE: str = wassima.generate_ca_bundle() diff --git a/src/niquests/_typing.py b/src/niquests/_typing.py index 34928e6a75..f4066d3444 100644 --- a/src/niquests/_typing.py +++ b/src/niquests/_typing.py @@ -134,3 +134,5 @@ CacheLayerAltSvcType: typing.TypeAlias = typing.MutableMapping[ typing.Tuple[str, int], typing.Optional[typing.Tuple[str, int]] ] + +RetryType: typing.TypeAlias = typing.Union[bool, int] diff --git a/src/niquests/api.py b/src/niquests/api.py index 9f71e3bdc7..1bd8d81280 100644 --- a/src/niquests/api.py +++ b/src/niquests/api.py @@ -12,7 +12,7 @@ import typing from . import sessions -from ._constant import READ_DEFAULT_TIMEOUT, WRITE_DEFAULT_TIMEOUT +from ._constant import DEFAULT_RETRIES, READ_DEFAULT_TIMEOUT, WRITE_DEFAULT_TIMEOUT from ._typing import ( BodyType, CacheLayerAltSvcType, @@ -25,6 +25,7 @@ MultiPartFilesType, ProxyType, QueryParameterType, + RetryType, TimeoutType, TLSClientCertType, TLSVerifyType, @@ -55,6 +56,7 @@ def request( stream: bool = False, cert: TLSClientCertType | None = None, hooks: HookType | None = None, + retries: RetryType = DEFAULT_RETRIES, ) -> Response: """Constructs and sends a :class:`Request `. @@ -99,7 +101,9 @@ def request( # By using the 'with' statement we are sure the session is closed, thus we # avoid leaving sockets open which can trigger a ResourceWarning in some # cases, and look like a memory leak in others. - with sessions.Session(quic_cache_layer=_SHARED_QUIC_CACHE) as session: + with sessions.Session( + quic_cache_layer=_SHARED_QUIC_CACHE, retries=retries + ) as session: return session.request( method=method, url=url, @@ -134,6 +138,7 @@ def get( stream: bool = False, cert: TLSClientCertType | None = None, hooks: HookType | None = None, + retries: RetryType = DEFAULT_RETRIES, ) -> Response: r"""Sends a GET request. @@ -158,6 +163,7 @@ def get( stream=stream, cert=cert, hooks=hooks, + retries=retries, ) @@ -175,6 +181,7 @@ def options( stream: bool = False, cert: TLSClientCertType | None = None, hooks: HookType | None = None, + retries: RetryType = DEFAULT_RETRIES, ) -> Response: r"""Sends an OPTIONS request. @@ -197,6 +204,7 @@ def options( stream=stream, cert=cert, hooks=hooks, + retries=retries, ) @@ -214,6 +222,7 @@ def head( stream: bool = False, cert: TLSClientCertType | None = None, hooks: HookType | None = None, + retries: RetryType = DEFAULT_RETRIES, ) -> Response: r"""Sends a HEAD request. @@ -236,6 +245,7 @@ def head( stream=stream, cert=cert, hooks=hooks, + retries=retries, ) @@ -256,6 +266,7 @@ def post( stream: bool = False, cert: TLSClientCertType | None = None, hooks: HookType | None = None, + retries: RetryType = DEFAULT_RETRIES, ) -> Response: r"""Sends a POST request. @@ -284,6 +295,7 @@ def post( stream=stream, cert=cert, hooks=hooks, + retries=retries, ) @@ -304,6 +316,7 @@ def put( stream: bool = False, cert: TLSClientCertType | None = None, hooks: HookType | None = None, + retries: RetryType = DEFAULT_RETRIES, ) -> Response: r"""Sends a PUT request. @@ -332,6 +345,7 @@ def put( stream=stream, cert=cert, hooks=hooks, + retries=retries, ) @@ -352,6 +366,7 @@ def patch( stream: bool = False, cert: TLSClientCertType | None = None, hooks: HookType | None = None, + retries: RetryType = DEFAULT_RETRIES, ) -> Response: r"""Sends a PATCH request. @@ -380,6 +395,7 @@ def patch( stream=stream, cert=cert, hooks=hooks, + retries=retries, ) @@ -396,6 +412,7 @@ def delete( stream: bool = False, cert: TLSClientCertType | None = None, hooks: HookType | None = None, + retries: RetryType = DEFAULT_RETRIES, ) -> Response: r"""Sends a DELETE request. @@ -417,4 +434,5 @@ def delete( stream=stream, cert=cert, hooks=hooks, + retries=retries, ) diff --git a/src/niquests/sessions.py b/src/niquests/sessions.py index 47f415a1a2..c5263be62d 100644 --- a/src/niquests/sessions.py +++ b/src/niquests/sessions.py @@ -18,7 +18,7 @@ from http.cookiejar import CookieJar from urllib.parse import urljoin, urlparse -from ._constant import READ_DEFAULT_TIMEOUT, WRITE_DEFAULT_TIMEOUT +from ._constant import DEFAULT_RETRIES, READ_DEFAULT_TIMEOUT, WRITE_DEFAULT_TIMEOUT from ._internal_utils import to_native_string from ._typing import ( BodyType, @@ -32,6 +32,7 @@ MultiPartFilesType, ProxyType, QueryParameterType, + RetryType, TimeoutType, TLSClientCertType, TLSVerifyType, @@ -165,7 +166,12 @@ class Session: "quic_cache_layer", ] - def __init__(self, quic_cache_layer: CacheLayerAltSvcType | None = None): + def __init__( + self, + *, + quic_cache_layer: CacheLayerAltSvcType | None = None, + retries: RetryType = DEFAULT_RETRIES, + ): #: A case-insensitive dictionary of headers to be sent on each #: :class:`Request ` sent from this #: :class:`Session `. @@ -228,8 +234,11 @@ def __init__(self, quic_cache_layer: CacheLayerAltSvcType | None = None): # Default connection adapters. self.adapters: OrderedDict[str, BaseAdapter] = OrderedDict() - self.mount("https://", HTTPAdapter(quic_cache_layer=self.quic_cache_layer)) - self.mount("http://", HTTPAdapter()) + self.mount( + "https://", + HTTPAdapter(quic_cache_layer=self.quic_cache_layer, max_retries=retries), + ) + self.mount("http://", HTTPAdapter(max_retries=retries)) def __enter__(self): return self