core-https 3.0.1__py3-none-any.whl → 3.1.1__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.
core_https/__init__.py CHANGED
@@ -1,18 +1,9 @@
1
- # -*- coding: utf-8 -*-
2
-
3
1
  """
4
2
  Public API for the core_https package: HTTP status codes
5
3
  and status info enum.
6
4
  """
7
5
 
8
- from importlib.metadata import PackageNotFoundError
9
- from importlib.metadata import version
10
-
11
- try:
12
- __version__ = version("core-https")
13
-
14
- except PackageNotFoundError:
15
- __version__ = "unknown"
6
+ from importlib.metadata import PackageNotFoundError, version
16
7
 
17
8
  from core_mixins.compatibility import StrEnum
18
9
 
@@ -23,10 +14,11 @@ except ImportError:
23
14
  from .utils import HTTPStatus as _HTTPStatus
24
15
 
25
16
 
26
- __all__ = [
27
- "HTTPStatus",
28
- "StatusInfo"
29
- ]
17
+ try:
18
+ __version__ = version("core-https")
19
+
20
+ except PackageNotFoundError:
21
+ __version__ = "unknown"
30
22
 
31
23
 
32
24
  # Type alias that works with both standard library
@@ -47,3 +39,10 @@ class StatusInfo(StrEnum):
47
39
  SUCCESS = "success"
48
40
  ERROR = "error"
49
41
  FAILURE = "failure"
42
+
43
+
44
+ __all__ = [
45
+ "HTTPStatus",
46
+ "StatusInfo",
47
+ "__version__",
48
+ ]
core_https/exceptions.py CHANGED
@@ -1,5 +1,3 @@
1
- # -*- coding: utf-8 -*-
2
-
3
1
  """
4
2
  HTTP client exception hierarchy for the core_https library.
5
3
 
@@ -1,5 +1,3 @@
1
- # -*- coding: utf-8 -*-
2
-
3
1
  """Asynchronous HTTP requester implementation backed by aiohttp."""
4
2
 
5
3
  from __future__ import annotations
@@ -7,8 +5,6 @@ from __future__ import annotations
7
5
  import asyncio
8
6
  from contextlib import suppress
9
7
  from typing import Any
10
- from typing import Dict
11
- from typing import Optional
12
8
 
13
9
  from aiohttp import (
14
10
  ClientResponse,
@@ -20,8 +16,8 @@ from aiohttp import (
20
16
  from core_mixins.compatibility import Self
21
17
 
22
18
  from core_https.exceptions import RetryableException
23
- from .base import HTTPMethod
24
- from .base import IRequester
19
+
20
+ from .base import HTTPMethod, IRequester
25
21
 
26
22
 
27
23
  class AioHttpRequester(IRequester):
@@ -80,8 +76,8 @@ class AioHttpRequester(IRequester):
80
76
 
81
77
  def __init__(
82
78
  self,
83
- session: Optional[ClientSession] = None,
84
- retries: Optional[int] = 3,
79
+ session: ClientSession | None = None,
80
+ retries: int | None = 3,
85
81
  **kwargs,
86
82
  ) -> None:
87
83
  """
@@ -110,7 +106,7 @@ class AioHttpRequester(IRequester):
110
106
  super().__init__(**kwargs)
111
107
 
112
108
  self._session = session
113
- self._session_lock: Optional[asyncio.Lock] = None
109
+ self._session_lock: asyncio.Lock | None = None
114
110
  self._owns_session = session is None
115
111
  self._timeout = ClientTimeout(total=self.timeout)
116
112
  self.retries = retries
@@ -152,16 +148,18 @@ class AioHttpRequester(IRequester):
152
148
  self._session_lock = asyncio.Lock()
153
149
 
154
150
  async with self._session_lock:
155
- if self._session is None: # Double-check after acquiring lock...
156
- self._session = ClientSession(
157
- timeout=self._timeout,
158
- connector=TCPConnector(
159
- limit=self.connector_limit,
160
- limit_per_host=self.connector_limit_per_host,
161
- ),
162
- )
151
+ if self._session is not None: # Double-check after acquiring lock...
152
+ return self._session
153
+
154
+ self._session = ClientSession(
155
+ timeout=self._timeout,
156
+ connector=TCPConnector(
157
+ limit=self.connector_limit,
158
+ limit_per_host=self.connector_limit_per_host,
159
+ ),
160
+ )
163
161
 
164
- self._owns_session = True
162
+ self._owns_session = True
165
163
 
166
164
  return self._session
167
165
 
@@ -169,12 +167,12 @@ class AioHttpRequester(IRequester):
169
167
  self,
170
168
  url: str,
171
169
  method: HTTPMethod = HTTPMethod.GET,
172
- headers: Optional[Dict[str, Any]] = None,
173
- retries: Optional[int] = None,
174
- backoff_factor: Optional[float] = None,
175
- session: Optional[ClientSession] = None,
176
- params: Optional[Dict[str, Any]] = None,
177
- timeout: Optional[float] = None,
170
+ headers: dict[str, Any] | None = None,
171
+ retries: int | None = None,
172
+ backoff_factor: float | None = None,
173
+ session: ClientSession | None = None,
174
+ params: dict[str, Any] | None = None,
175
+ timeout: float | None = None,
178
176
  **kwargs,
179
177
  ) -> ClientResponse:
180
178
  """
@@ -1,5 +1,3 @@
1
- # -*- coding: utf-8 -*-
2
-
3
1
  """Rate-limited aiohttp requester using aiolimiter.AsyncLimiter."""
4
2
 
5
3
  from aiohttp import ClientResponse
@@ -17,12 +15,7 @@ class AioHttpRateLimitRequester(AioHttpRequester):
17
15
  if they acquire permission within the same window.
18
16
  """
19
17
 
20
- def __init__(
21
- self,
22
- max_rate: int,
23
- time_period: float,
24
- **kwargs
25
- ) -> None:
18
+ def __init__(self, max_rate: int, time_period: float, **kwargs) -> None:
26
19
  """
27
20
  Initialize the rate-limited requester.
28
21
 
@@ -1,9 +1,8 @@
1
- # -*- coding: utf-8 -*-
2
-
3
1
  """Concurrency-throttled aiohttp requester using asyncio.Semaphore."""
4
2
 
3
+ from __future__ import annotations
4
+
5
5
  import asyncio
6
- from typing import Optional
7
6
 
8
7
  from aiohttp import ClientResponse
9
8
 
@@ -37,7 +36,7 @@ class AioHttpThrottleRequester(AioHttpRequester):
37
36
 
38
37
  super().__init__(**kwargs)
39
38
  self.max_concurrency = max_concurrency
40
- self._semaphore: Optional[asyncio.Semaphore] = None
39
+ self._semaphore: asyncio.Semaphore | None = None
41
40
 
42
41
  @classmethod
43
42
  def engine(cls) -> str:
@@ -1,11 +1,11 @@
1
- # -*- coding: utf-8 -*-
2
-
3
1
  """Abstract base class and shared utilities for all HTTP requester implementations."""
4
2
 
3
+ from __future__ import annotations
4
+
5
5
  import re
6
- from abc import ABC
7
- from abc import abstractmethod
8
- from typing import Any, Dict, Mapping, Optional
6
+ from abc import ABC, abstractmethod
7
+ from collections.abc import Mapping
8
+ from typing import Any
9
9
 
10
10
  from core_mixins.interfaces.factory import IFactory
11
11
 
@@ -85,8 +85,8 @@ class IRequester(IFactory, ABC):
85
85
  self,
86
86
  encoding: str = "utf-8",
87
87
  raise_for_status: bool = False,
88
- retries: Optional[Any] = None,
89
- backoff_factor: Optional[float] = None,
88
+ retries: Any | None = None,
89
+ backoff_factor: float | None = None,
90
90
  connector_limit: int = 100,
91
91
  connector_limit_per_host: int = 30,
92
92
  timeout: int = 10,
@@ -195,9 +195,9 @@ class IRequester(IFactory, ABC):
195
195
  self,
196
196
  url: str,
197
197
  method: HTTPMethod,
198
- headers: Optional[Dict[str, str]] = None,
199
- retries: Optional[Any] = None,
200
- backoff_factor: Optional[float] = None,
198
+ headers: dict[str, str] | None = None,
199
+ retries: Any | None = None,
200
+ backoff_factor: float | None = None,
201
201
  **kwargs, # Each `engine`have its own attributes...
202
202
  ) -> Any:
203
203
  """
@@ -293,10 +293,7 @@ class IRequester(IFactory, ABC):
293
293
  - The method gracefully handles malformed or missing headers
294
294
  """
295
295
 
296
- headers_ = {
297
- k.lower(): v
298
- for k, v in headers.items()
299
- }
296
+ headers_ = {k.lower(): v for k, v in headers.items()}
300
297
 
301
298
  # First trying "charset" header directly (rare)...
302
299
  charset = headers_.get("charset")
@@ -307,12 +304,7 @@ class IRequester(IFactory, ABC):
307
304
  content_type = headers_.get("content-type", "")
308
305
  match = re.search(r"charset=([^\s;]+)", content_type, re.IGNORECASE)
309
306
  if match:
310
- return (
311
- match.group(1)
312
- .strip()
313
- .replace("'", "")
314
- .replace('"', "")
315
- )
307
+ return match.group(1).strip().replace("'", "").replace('"', "")
316
308
 
317
309
  return self.encoding or default
318
310
 
@@ -1,14 +1,13 @@
1
- # -*- coding: utf-8 -*-
2
-
3
1
  """Synchronous HTTP requester implementation backed by the requests library."""
4
2
 
5
- from typing import Dict, Optional
3
+ from __future__ import annotations
6
4
 
7
5
  import requests
8
6
  import urllib3
9
7
  from requests.adapters import HTTPAdapter
10
8
 
11
9
  from core_https.requesters.base import IRequester
10
+
12
11
  from .base import HTTPMethod
13
12
 
14
13
 
@@ -36,9 +35,9 @@ class RequestsRequester(IRequester):
36
35
 
37
36
  def __init__(
38
37
  self,
39
- session: Optional[requests.Session] = None,
40
- retries: Optional[urllib3.Retry] = None,
41
- backoff_factor: Optional[float] = None,
38
+ session: requests.Session | None = None,
39
+ retries: urllib3.Retry | None = None,
40
+ backoff_factor: float | None = None,
42
41
  **kwargs,
43
42
  ) -> None:
44
43
  """
@@ -86,12 +85,12 @@ class RequestsRequester(IRequester):
86
85
  self,
87
86
  url: str,
88
87
  method: HTTPMethod = HTTPMethod.GET,
89
- headers: Optional[Dict[str, str]] = None,
90
- retries: Optional[urllib3.Retry] = None,
91
- backoff_factor: Optional[float] = None,
92
- session: Optional[requests.Session] = None,
93
- params: Optional[Dict] = None,
94
- timeout: Optional[float] = None,
88
+ headers: dict[str, str] | None = None,
89
+ retries: urllib3.Retry | None = None,
90
+ backoff_factor: float | None = None,
91
+ session: requests.Session | None = None,
92
+ params: dict | None = None,
93
+ timeout: float | None = None,
95
94
  **kwargs,
96
95
  ) -> requests.Response:
97
96
  """
@@ -1,17 +1,13 @@
1
- # -*- coding: utf-8 -*-
2
-
3
1
  """Low-level synchronous HTTP requester implementation backed by urllib3."""
4
2
 
3
+ from __future__ import annotations
4
+
5
5
  import json
6
6
  from contextlib import suppress
7
- from typing import Dict, Optional
8
7
 
9
- from urllib3 import BaseHTTPResponse
10
- from urllib3 import PoolManager
11
- from urllib3 import Retry
8
+ from urllib3 import BaseHTTPResponse, PoolManager, Retry
12
9
 
13
- from .base import HTTPMethod
14
- from .base import IRequester
10
+ from .base import HTTPMethod, IRequester
15
11
 
16
12
 
17
13
  class Urllib3Requester(IRequester):
@@ -31,8 +27,8 @@ class Urllib3Requester(IRequester):
31
27
 
32
28
  def __init__(
33
29
  self,
34
- pool_manager: Optional[PoolManager] = None,
35
- retries: Optional[Retry] = None,
30
+ pool_manager: PoolManager | None = None,
31
+ retries: Retry | None = None,
36
32
  **kwargs,
37
33
  ) -> None:
38
34
  """
@@ -56,11 +52,11 @@ class Urllib3Requester(IRequester):
56
52
  self,
57
53
  url: str,
58
54
  method: HTTPMethod = HTTPMethod.GET,
59
- headers: Optional[Dict[str, str]] = None,
60
- retries: Optional[Retry] = None,
61
- backoff_factor: Optional[float] = None,
62
- fields: Optional[Dict] = None,
63
- timeout: Optional[float] = None,
55
+ headers: dict[str, str] | None = None,
56
+ retries: Retry | None = None,
57
+ backoff_factor: float | None = None,
58
+ fields: dict | None = None,
59
+ timeout: float | None = None,
64
60
  **kwargs,
65
61
  ) -> BaseHTTPResponse:
66
62
  """
@@ -1,5 +1,3 @@
1
- # -*- coding: utf-8 -*-
2
-
3
1
  """
4
2
  Test utilities for aiohttp HTTP client library.
5
3
 
@@ -38,7 +36,9 @@ See Also:
38
36
  - BaseUrllib3TestCases: Test utilities for urllib3 library
39
37
  """
40
38
 
41
- from typing import Any, Dict, List, Optional
39
+ from __future__ import annotations
40
+
41
+ from typing import Any
42
42
  from unittest.mock import AsyncMock, Mock
43
43
 
44
44
  from aiohttp import ClientResponseError
@@ -103,14 +103,14 @@ class BaseAiohttpTestCases(BaseHttpTestCases):
103
103
  cls,
104
104
  url: str = "https://example.com",
105
105
  method: str = "GET",
106
- json_response: Optional[Dict[str, Any]] = None,
106
+ json_response: dict[str, Any] | None = None,
107
107
  status: int = 200,
108
- headers: Optional[Dict[str, str]] = None,
109
- text_response: Optional[str] = None,
110
- content: Optional[bytes] = None,
108
+ headers: dict[str, str] | None = None,
109
+ text_response: str | None = None,
110
+ content: bytes | None = None,
111
111
  content_type: str = "application/json",
112
112
  charset: str = "utf-8",
113
- raise_for_status_exception: Optional[Exception] = None,
113
+ raise_for_status_exception: Exception | None = None,
114
114
  ) -> Mock:
115
115
  """
116
116
  Create a mock aiohttp.ClientResponse object for testing.
@@ -203,7 +203,7 @@ class BaseAiohttpTestCases(BaseHttpTestCases):
203
203
  url: str = "http://example.com",
204
204
  status: int = 404,
205
205
  message: str = "Not Found",
206
- history: Optional[List] = None,
206
+ history: list | None = None,
207
207
  ) -> ClientResponseError:
208
208
  """
209
209
  Create a ClientResponseError for testing error handling.
core_https/tests/base.py CHANGED
@@ -1,5 +1,3 @@
1
- # -*- coding: utf-8 -*-
2
-
3
1
  """
4
2
  Base test case classes for HTTP request testing.
5
3
 
@@ -27,7 +25,6 @@ See Also:
27
25
  - BaseUrllib3TestCases: Specialized test utilities for urllib3 library
28
26
  """
29
27
 
30
- from typing import Dict
31
28
  from unittest import TestCase
32
29
 
33
30
  from core_https.utils import HTTPStatus
@@ -83,4 +80,4 @@ class BaseHttpTestCases(TestCase):
83
80
 
84
81
  # Dictionary mapping HTTP status codes to their reason phrases.
85
82
  # Generated from :class:`HTTPStatus` enum.
86
- code_mapper: Dict[int, str] = HTTPStatus.as_dict()
83
+ code_mapper: dict[int, str] = HTTPStatus.as_dict()
@@ -1,5 +1,3 @@
1
- # -*- coding: utf-8 -*-
2
-
3
1
  """
4
2
  Test decorators for HTTP library mocking.
5
3
 
@@ -26,8 +24,10 @@ See Also:
26
24
  - BaseUrllib3TestCases: Base class for urllib3 test utilities.
27
25
  """
28
26
 
27
+ from __future__ import annotations
28
+
29
29
  from functools import wraps
30
- from typing import Any, Dict, Optional
30
+ from typing import Any
31
31
  from unittest.mock import AsyncMock, Mock, patch
32
32
 
33
33
  from .aiohttp_ import BaseAiohttpTestCases
@@ -38,14 +38,14 @@ from .urllib3_ import BaseUrllib3TestCases
38
38
  def patch_aiohttp(
39
39
  url: str = "https://example.com",
40
40
  method: str = "GET",
41
- json_response: Optional[Dict[str, Any]] = None,
41
+ json_response: dict[str, Any] | None = None,
42
42
  status: int = 200,
43
- headers: Optional[Dict[str, str]] = None,
44
- text_response: Optional[str] = None,
45
- content: Optional[bytes] = None,
43
+ headers: dict[str, str] | None = None,
44
+ text_response: str | None = None,
45
+ content: bytes | None = None,
46
46
  content_type: str = "application/json",
47
47
  charset: str = "utf-8",
48
- raise_for_status_exception: Optional[Exception] = None,
48
+ raise_for_status_exception: Exception | None = None,
49
49
  ):
50
50
  """
51
51
  Decorator that patches `aiohttp.ClientSession._request` with
@@ -127,12 +127,12 @@ def patch_aiohttp(
127
127
  def patch_requests(
128
128
  url: str = "https://example.com",
129
129
  encoding: str = "utf-8",
130
- headers: Optional[Dict[str, str]] = None,
131
- json_response: Optional[Dict[str, Any]] = None,
132
- text_response: Optional[str] = None,
130
+ headers: dict[str, str] | None = None,
131
+ json_response: dict[str, Any] | None = None,
132
+ text_response: str | None = None,
133
133
  status_code: int = 200,
134
- content: Optional[bytes] = None,
135
- raise_for_status_exception: Optional[Exception] = None,
134
+ content: bytes | None = None,
135
+ raise_for_status_exception: Exception | None = None,
136
136
  ):
137
137
  """
138
138
  Decorator that patches requests.sessions.Session.request to
@@ -217,17 +217,17 @@ def patch_urllib3(
217
217
  method: str = "GET",
218
218
  status: int = 200,
219
219
  data: bytes = b'{"message": "success"}',
220
- headers: Optional[Dict[str, str]] = None,
221
- reason: Optional[str] = None,
220
+ headers: dict[str, str] | None = None,
221
+ reason: str | None = None,
222
222
  version: int = 11,
223
223
  preload_content: bool = True,
224
224
  decode_content: bool = True,
225
225
  version_string: str = "HTTP/1.1",
226
- original_response: Optional[Mock] = None,
227
- pool: Optional[Mock] = None,
228
- connection: Optional[Mock] = None,
229
- msg: Optional[Mock] = None,
230
- retries: Optional[Mock] = None,
226
+ original_response: Mock | None = None,
227
+ pool: Mock | None = None,
228
+ connection: Mock | None = None,
229
+ msg: Mock | None = None,
230
+ retries: Mock | None = None,
231
231
  enforce_content_length: bool = False,
232
232
  with_json_attr: bool = True,
233
233
  ):
@@ -1,5 +1,3 @@
1
- # -*- coding: utf-8 -*-
2
-
3
1
  """
4
2
  Test utilities for requests HTTP client library.
5
3
 
@@ -37,8 +35,10 @@ See Also:
37
35
  - BaseUrllib3TestCases: Test utilities for urllib3 library
38
36
  """
39
37
 
38
+ from __future__ import annotations
39
+
40
40
  import json
41
- from typing import Any, Dict, Optional
41
+ from typing import Any
42
42
  from unittest.mock import Mock
43
43
 
44
44
  from core_https.tests.base import BaseHttpTestCases
@@ -105,12 +105,12 @@ class BaseRequestsTestCases(BaseHttpTestCases):
105
105
  cls,
106
106
  url: str = "https://example.com",
107
107
  encoding: str = "utf-8",
108
- headers: Optional[Dict[str, str]] = None,
109
- json_response: Optional[Dict[str, Any]] = None,
110
- text_response: Optional[str] = None,
108
+ headers: dict[str, str] | None = None,
109
+ json_response: dict[str, Any] | None = None,
110
+ text_response: str | None = None,
111
111
  status_code: int = 200,
112
- content: Optional[bytes] = None,
113
- raise_for_status_exception: Optional[Exception] = None,
112
+ content: bytes | None = None,
113
+ raise_for_status_exception: Exception | None = None,
114
114
  ) -> Mock:
115
115
  """
116
116
  Create a mock requests.Response object for testing.
@@ -1,5 +1,3 @@
1
- # -*- coding: utf-8 -*-
2
-
3
1
  """
4
2
  Test utilities for urllib3 HTTP client library.
5
3
 
@@ -43,8 +41,9 @@ See Also:
43
41
  - BaseAiohttpTestCases: Test utilities for aiohttp library
44
42
  """
45
43
 
44
+ from __future__ import annotations
45
+
46
46
  import json
47
- from typing import Dict, Optional
48
47
  from unittest.mock import Mock
49
48
 
50
49
  from urllib3._collections import HTTPHeaderDict
@@ -114,17 +113,17 @@ class BaseUrllib3TestCases(BaseHttpTestCases):
114
113
  method: str = "GET",
115
114
  status: int = 200,
116
115
  data: bytes = b'{"message": "success"}',
117
- headers: Optional[Dict[str, str]] = None,
118
- reason: Optional[str] = None,
116
+ headers: dict[str, str] | None = None,
117
+ reason: str | None = None,
119
118
  version: int = 11,
120
119
  preload_content: bool = True,
121
120
  decode_content: bool = True,
122
121
  version_string: str = "HTTP/1.1",
123
- original_response: Optional[Mock] = None,
124
- pool: Optional[Mock] = None,
125
- connection: Optional[Mock] = None,
126
- msg: Optional[Mock] = None,
127
- retries: Optional[Mock] = None,
122
+ original_response: Mock | None = None,
123
+ pool: Mock | None = None,
124
+ connection: Mock | None = None,
125
+ msg: Mock | None = None,
126
+ retries: Mock | None = None,
128
127
  enforce_content_length: bool = False,
129
128
  with_json_attr: bool = True,
130
129
  ) -> Mock:
core_https/utils.py CHANGED
@@ -1,5 +1,3 @@
1
- # -*- coding: utf-8 -*-
2
-
3
1
  """
4
2
  HTTP utilities for the core_https library.
5
3
 
@@ -48,7 +46,6 @@ See Also:
48
46
  """
49
47
 
50
48
  from enum import Enum
51
- from typing import Dict
52
49
 
53
50
 
54
51
  class HTTPStatus(Enum):
@@ -226,7 +223,7 @@ class HTTPStatus(Enum):
226
223
  raise ValueError(f"No HTTPStatus found for code: {code}") from exc
227
224
 
228
225
  @classmethod
229
- def as_dict(cls) -> Dict[int, str]:
226
+ def as_dict(cls) -> dict[int, str]:
230
227
  """
231
228
  Get all HTTP status codes as a dictionary.
232
229
 
@@ -238,13 +235,10 @@ class HTTPStatus(Enum):
238
235
  print(codes[200]) # "OK"
239
236
  """
240
237
 
241
- return {
242
- member.code: member.description
243
- for member in cls
244
- }
238
+ return {member.code: member.description for member in cls}
245
239
 
246
240
 
247
- _HTTP_STATUS_BY_CODE: Dict[int, HTTPStatus] = {m.value: m for m in HTTPStatus}
241
+ _HTTP_STATUS_BY_CODE: dict[int, HTTPStatus] = {m.value: m for m in HTTPStatus}
248
242
 
249
243
 
250
244
  class HTTPMethod(Enum):
@@ -312,7 +306,12 @@ class HTTPMethod(Enum):
312
306
 
313
307
  Safe methods are those that do not modify server state.
314
308
  """
315
- return self in (HTTPMethod.GET, HTTPMethod.HEAD, HTTPMethod.OPTIONS, HTTPMethod.TRACE)
309
+ return self in (
310
+ HTTPMethod.GET,
311
+ HTTPMethod.HEAD,
312
+ HTTPMethod.OPTIONS,
313
+ HTTPMethod.TRACE,
314
+ )
316
315
 
317
316
  def is_idempotent(self) -> bool:
318
317
  """
@@ -320,8 +319,14 @@ class HTTPMethod(Enum):
320
319
 
321
320
  Idempotent methods can be called multiple times with the same result.
322
321
  """
323
- return self in (HTTPMethod.GET, HTTPMethod.HEAD, HTTPMethod.PUT, HTTPMethod.DELETE,
324
- HTTPMethod.OPTIONS, HTTPMethod.TRACE)
322
+ return self in (
323
+ HTTPMethod.GET,
324
+ HTTPMethod.HEAD,
325
+ HTTPMethod.PUT,
326
+ HTTPMethod.DELETE,
327
+ HTTPMethod.OPTIONS,
328
+ HTTPMethod.TRACE,
329
+ )
325
330
 
326
331
  def is_cacheable(self) -> bool:
327
332
  """
@@ -358,4 +363,4 @@ class HTTPMethod(Enum):
358
363
  raise ValueError(f"No HTTPMethod found for name: {name}") from exc
359
364
 
360
365
 
361
- _HTTP_METHOD_BY_NAME: Dict[str, HTTPMethod] = {m.value: m for m in HTTPMethod}
366
+ _HTTP_METHOD_BY_NAME: dict[str, HTTPMethod] = {m.value: m for m in HTTPMethod}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: core-https
3
- Version: 3.0.1
3
+ Version: 3.1.1
4
4
  Summary: This project/library contains common elements related to HTTP & API services...
5
5
  Author-email: Alejandro Cora González <alek.cora.glez@gmail.com>
6
6
  Maintainer: Alejandro Cora González
@@ -27,13 +27,13 @@ Requires-Python: >=3.9
27
27
  Description-Content-Type: text/x-rst
28
28
  License-File: LICENSE
29
29
  Requires-Dist: aiohttp<4.0.0,>=3.12.0
30
- Requires-Dist: core-mixins>=3.0.1
30
+ Requires-Dist: core-mixins>=3.2.2
31
31
  Requires-Dist: requests<3.0.0,>=2.32.3
32
32
  Requires-Dist: urllib3<3.0.0,>=2.2.3
33
33
  Provides-Extra: dev
34
34
  Requires-Dist: aiolimiter<2.0.0,>=1.2.1; extra == "dev"
35
- Requires-Dist: core-dev-tools>=1.2.1; extra == "dev"
36
- Requires-Dist: core-tests>=2.0.5; extra == "dev"
35
+ Requires-Dist: core-dev-tools>=2.1.0; extra == "dev"
36
+ Requires-Dist: core-tests>=2.3.0; extra == "dev"
37
37
  Requires-Dist: types-requests>=2.32.0.20250602; extra == "dev"
38
38
  Provides-Extra: extras
39
39
  Requires-Dist: aiolimiter<2.0.0,>=1.2.1; extra == "extras"
@@ -46,6 +46,10 @@ This project/library contains common elements related to HTTP...
46
46
 
47
47
  ===============================================================================
48
48
 
49
+ .. image:: https://static.pepy.tech/personalized-badge/core-https?period=total&units=INTERNATIONAL_SYSTEM&left_color=BLACK&right_color=GREEN&left_text=downloads
50
+ :target: https://pepy.tech/projects/core-https
51
+ :alt: PyPI Downloads
52
+
49
53
  .. image:: https://img.shields.io/pypi/pyversions/core-https.svg
50
54
  :target: https://pypi.org/project/core-https/
51
55
  :alt: Python Versions
@@ -0,0 +1,22 @@
1
+ core_https/__init__.py,sha256=YssKKc3kkQNLYHcXKyqb2u4ocGKL-nCs1SXyUHxHxBw,984
2
+ core_https/exceptions.py,sha256=kocOWT8_TQ3VS_IgCmo3hSJhNG5ytQn5f7eLpNhSk6E,4936
3
+ core_https/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ core_https/utils.py,sha256=vWpVw3UEK2lmFf4Fh3MakiAaE53KHYM9nZvC2Q-inbc,12298
5
+ core_https/requesters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
+ core_https/requesters/aiohttp_.py,sha256=wIWLhu62QqgglJijbPs3DuFLtV46Gj-UOVF0Jf-UVA4,11223
7
+ core_https/requesters/aiohttp_rate_limit.py,sha256=oY2dsdSrRuHRA0VV2ZoEAy3_ypVp46sa2FMX1NhZpW0,2033
8
+ core_https/requesters/aiohttp_throttle.py,sha256=BQVkcVv0l4xubCkVxKP7Gx5zrGw1KNOewZZjKiMncKU,2316
9
+ core_https/requesters/base.py,sha256=CVeqmaqCST5ZoBc46wqmpzmml0a-TGgqepPg1r4Y0o8,16441
10
+ core_https/requesters/requests_.py,sha256=ImGq4w--fGy7boRP0qZ0LQYgvXsyUZi5ZYCvSDGKCbk,3328
11
+ core_https/requesters/urllib3_.py,sha256=BFtOEBblnQaD0XoQrKuv7RW0hMdptiqP_mLoGi36WLY,3469
12
+ core_https/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
+ core_https/tests/aiohttp_.py,sha256=y2Mrg5iypSbswi7JFHAwRQycrOTzHow_RkjehZXQpbk,9593
14
+ core_https/tests/base.py,sha256=Qrr1kDhGg84V58_nY37OUWuBO13cKCzQ-SadsunZBLw,3387
15
+ core_https/tests/decorators.py,sha256=g1fvKnrfKv1xqYEbeWWLCLz958TlOhu5IVwoO9TAUU0,12891
16
+ core_https/tests/requests_.py,sha256=MO1rxE-1aWXlZ-qyhUfq_AEyNz7MNHq3jNeB6y91buA,8274
17
+ core_https/tests/urllib3_.py,sha256=UPCQkhbbNw2lT7ICBrFLlNEKZADNN3iYE7gkCGNGjrc,13166
18
+ core_https-3.1.1.dist-info/licenses/LICENSE,sha256=dj8Wz7OWOIOTyLJzaYLn8RFz_W5uYWSGR2xS5lHNAl4,1082
19
+ core_https-3.1.1.dist-info/METADATA,sha256=dK5JQ-DJW5DNmVg-L-ddbuzQ9KzDErGU3RTNeapPNNI,7216
20
+ core_https-3.1.1.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
21
+ core_https-3.1.1.dist-info/top_level.txt,sha256=Ufm6w6dLS6hyTPwMUXt4O6klJfLyKpkaG6csd2kmaDw,11
22
+ core_https-3.1.1.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (82.0.1)
2
+ Generator: setuptools (84.0.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,22 +0,0 @@
1
- core_https/__init__.py,sha256=hc9GShxIeLa0txghXE4Uwe2lkOrbzrXK2d111c_baXE,1018
2
- core_https/exceptions.py,sha256=l0NKIGi5NeJ2Aw-231txK24CIv-tgceKBvP2_u2i3jw,4961
3
- core_https/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- core_https/utils.py,sha256=PJbKgOFAXAMTfwcuIFMK2zKwdqFIPh8ixJDgpzdhmFA,12262
5
- core_https/requesters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
- core_https/requesters/aiohttp_.py,sha256=nDnjSb9rxi2HYOkAQPQ_Ypi2irG_WWoFY-Oiy6rg1HA,11329
7
- core_https/requesters/aiohttp_rate_limit.py,sha256=_qEwu2QvNAu0DcxSxKaIEQF4du_4_NcHhVwdcDAO9DI,2096
8
- core_https/requesters/aiohttp_throttle.py,sha256=gC_UURL6rgOOHON2qGLK8hByLOYrlxCIy4bDlWedwPc,2336
9
- core_https/requesters/base.py,sha256=rzZ-MOBDBS17GWQwD4-_LWszpOv1vCReRyRY9RpylT8,16578
10
- core_https/requesters/requests_.py,sha256=pFgMB-ajFJGPS9FfZzbEgN1vnMVRoExz3E_6I-496eI,3378
11
- core_https/requesters/urllib3_.py,sha256=DVJ4qmjWPHH9FiVbMnEjEUR0kztB6s1gnOHPrN_TTvs,3568
12
- core_https/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
- core_https/tests/aiohttp_.py,sha256=NChlPeyaAMa7p1OtfuC5yZx2E-XQAXm_NTsFnGZjDQE,9622
14
- core_https/tests/base.py,sha256=Nx_nLR7927F1UShva3YJ5gkqtKQaU6g2rpkO__Ph5qg,3436
15
- core_https/tests/decorators.py,sha256=9wa_omtkJ7ImUDOyy69vYRt-Ulzkah4H2UT7gjAhtxQ,12947
16
- core_https/tests/requests_.py,sha256=Wja7zI_zkOH8DNnY3RJCJQSPghkVS36-WGZSee4ZSmE,8294
17
- core_https/tests/urllib3_.py,sha256=zKYroybSItnWa7BU1bGG4HSh0O7H1jNn6JKDLUPx5Nc,13210
18
- core_https-3.0.1.dist-info/licenses/LICENSE,sha256=dj8Wz7OWOIOTyLJzaYLn8RFz_W5uYWSGR2xS5lHNAl4,1082
19
- core_https-3.0.1.dist-info/METADATA,sha256=fN2SMJFdQ-qNnPFx5D3lQyvaLn5L0DrzkqDmdWLHAco,6978
20
- core_https-3.0.1.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
21
- core_https-3.0.1.dist-info/top_level.txt,sha256=Ufm6w6dLS6hyTPwMUXt4O6klJfLyKpkaG6csd2kmaDw,11
22
- core_https-3.0.1.dist-info/RECORD,,