1
1
"""
2
2
Python HTTP library with thread-safe connection pooling, file post support, user friendly, and more
3
3
"""
4
- from __future__ import absolute_import
4
+
5
+ from __future__ import annotations
5
6
6
7
# Set default logging handler to avoid "No handler found" warnings.
7
8
import logging
9
+ import sys
10
+ import typing
8
11
import warnings
9
12
from logging import NullHandler
10
13
11
14
from . import exceptions
15
+ from ._base_connection import _TYPE_BODY
16
+ from ._collections import HTTPHeaderDict
12
17
from ._version import __version__
13
18
from .connectionpool import HTTPConnectionPool , HTTPSConnectionPool , connection_from_url
14
- from .filepost import encode_multipart_formdata
19
+ from .filepost import _TYPE_FIELDS , encode_multipart_formdata
15
20
from .poolmanager import PoolManager , ProxyManager , proxy_from_url
16
- from .response import HTTPResponse
21
+ from .response import BaseHTTPResponse , HTTPResponse
17
22
from .util .request import make_headers
18
23
from .util .retry import Retry
19
24
from .util .timeout import Timeout
20
- from .util .url import get_host
21
25
22
- # === NOTE TO REPACKAGERS AND VENDORS ===
23
- # Please delete this block, this logic is only
24
- # for urllib3 being distributed via PyPI.
25
- # See: https://github.com/urllib3/urllib3/issues/2680
26
+ # Ensure that Python is compiled with OpenSSL 1.1.1+
27
+ # If the 'ssl' module isn't available at all that's
28
+ # fine, we only care if the module is available.
26
29
try :
27
- import urllib3_secure_extra # type: ignore # noqa: F401
30
+ import ssl
28
31
except ImportError :
29
32
pass
30
33
else :
31
- warnings .warn (
32
- "'urllib3[secure]' extra is deprecated and will be remove
10000
d "
33
- "in a future release of urllib3 2.x. Read more in this issue: "
34
- "https://github.com/urllib3/urllib3/issues/2680" ,
35
- category = DeprecationWarning ,
36
- stacklevel = 2 ,
37
- )
34
+ if not ssl .OPENSSL_VERSION .startswith ("OpenSSL " ): # Defensive:
35
+ warnings .warn (
36
+ "urllib3 v2 only supports OpenSSL 1.1.1+, currently "
37
+ f"the 'ssl' module is compiled with { ssl .OPENSSL_VERSION !r} . "
38
+ "See: https://github.com/urllib3/urllib3/issues/3020" ,
39
+ exceptions .NotOpenSSLWarning ,
40
+ )
41
+ elif ssl .OPENSSL_VERSION_INFO < (1 , 1 , 1 ): # Defensive:
42
+ raise ImportError (
43
+ "urllib3 v2 only supports OpenSSL 1.1.1+, currently "
44
+ f"the 'ssl' module is compiled with { ssl .OPENSSL_VERSION !r} . "
45
+ "See: https://github.com/urllib3/urllib3/issues/2168"
46
+ )
38
47
39
48
__author__ = "Andrey Petrov (andrey.petrov@shazow.net)"
40
49
__license__ = "MIT"
41
50
__version__ = __version__
42
51
43
52
__all__ = (
44
53
"HTTPConnectionPool" ,
54
+ "HTTPHeaderDict" ,
45
55
"HTTPSConnectionPool" ,
46
56
"PoolManager" ,
47
57
"ProxyManager" ,
52
62
"connection_from_url" ,
53
63
"disable_warnings" ,
54
64
"encode_multipart_formdata" ,
55
- "get_host" ,
56
65
"make_headers" ,
57
66
"proxy_from_url" ,
67
+ "request" ,
68
+ "BaseHTTPResponse" ,
58
69
)
59
70
60
71
logging .getLogger (__name__ ).addHandler (NullHandler ())
61
72
62
73
63
- def add_stderr_logger (level = logging .DEBUG ):
74
+ def add_stderr_logger (
75
+ level : int = logging .DEBUG ,
76
+ ) -> logging .StreamHandler [typing .TextIO ]:
64
77
"""
65
78
Helper for quickly adding a StreamHandler to the logger. Useful for
66
79
debugging.
@@ -87,16 +100,112 @@ def add_stderr_logger(level=logging.DEBUG):
87
100
# mechanisms to silence them.
88
101
# SecurityWarning's always go off by default.
89
102
warnings .simplefilter ("always" , exceptions .SecurityWarning , append = True )
90
- # SubjectAltNameWarning's should go off once per host
91
- warnings .simplefilter ("default" , exceptions .SubjectAltNameWarning , append = True )
92
103
# InsecurePlatformWarning's don't vary between requests, so we keep it default.
93
104
warnings .simplefilter ("default" , exceptions .InsecurePlatformWarning , append = True )
94
- # SNIMissingWarnings should go off only once.
95
- warnings .simplefilter ("default" , exceptions .SNIMissingWarning , append = True )
96
105
97
106
98
- def disable_warnings (category = exceptions .HTTPWarning ):
107
+ def disable_warnings (category : type [ Warning ] = exceptions .HTTPWarning ) -> None :
99
108
"""
100
109
Helper for quickly disabling all urllib3 warnings.
101
110
"""
102
111
warnings .simplefilter ("ignore" , category )
112
+
113
+
114
+ _DEFAULT_POOL = PoolManager ()
115
+
116
+
117
+ def request (
118
+ method : str ,
119
+ url : str ,
120
+ * ,
121
+ body : _TYPE_BODY | None = None ,
122
+ fields : _TYPE_FIELDS | None = None ,
123
+ headers : typing .Mapping [str , str ] | None = None ,
124
+ preload_content : bool | None = True ,
125
+ decode_content : bool | None = True ,
126
+ redirect : bool | None = True ,
127
+ retries : Retry | bool | int | None = None ,
128
+ timeout : Timeout | float | int | None = 3 ,
129
+ json : typing .Any | None = None ,
130
+ ) -> BaseHTTPResponse :
131
+ """
132
+ A convenience, top-level request method. It uses a module-global ``PoolManager`` instance.
133
+ Therefore, its side effects could be shared across dependencies relying on it.
134
+ To avoid side effects create a new ``PoolManager`` instance and use it instead.
135
+ The method does not accept low-level ``**urlopen_kw`` keyword arguments.
136
+
137
+ :param method:
138
+ HTTP request method (such as GET, POST, PUT, etc.)
139
+
140
+ :param url:
141
+ The URL to perform the request on.
142
+
143
+ :param body:
144
+ Data to send in the request body, either :class:`str`, :class:`bytes`,
145
+ an iterable of :class:`str`/:class:`bytes`, or a file-like object.
146
+
147
+ :param fields:
148
+ Data to encode and send in the request body.
149
+
150
+ :param headers:
151
+ Dictionary of custom headers to send, such as User-Agent,
152
+ If-None-Match, etc.
153
+
154
+ :param bool preload_content:
155
+ If True, the response's body will be preloaded into memory.
156
+
157
+ :param bool decode_content:
158
+ If True, will attempt to decode the body based on the
159
+ 'content-encoding' header.
160
+
161
+ :param redirect:
162
+ If True, automatically handle redirects (status codes 301, 302,
163
+ 303, 307, 308). Each redirect counts as a retry. Disabling retries
164
+ will disable redirect, too.
165
+
166
+ :param retries:
167
+ Configure the number of retries to allow before raising a
168
+ :class:`~urllib3.exceptions.MaxRetryError` exception.
169
+
170
+ If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a
171
+ :class:`~urllib3.util.retry.Retry` object for fine-grained control
172
+ over different types of retries.
173
+ Pass an integer number to retry connection errors that many times,
174
+ but no other types of errors. Pass zero to never retry.
175
+
176
+ If ``False``, then retries are disabled and any exception is raised
177
+ immediately. Also, instead of raising a MaxRetryError on redirects,
178
+ the redirect response will be returned.
179
+
180
+ :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int.
181
+
182
+ :param timeout:
183
+ If specified, overrides the default timeout for this one
184
+ request. It may be a float (in seconds) or an instance of
185
+ :class:`urllib3.util.Timeout`.
186
+
187
+ :param json:
188
+ Data to encode and send as JSON with UTF-encoded in the request body.
189
+ The ``"Content-Type"`` header will be set to ``"application/json"``
190
+ unless specified otherwise.
191
+ """
192
+
193
+ return _DEFAULT_POOL .request (
194
+ method ,
195
+ url ,
196
+ body = body ,
197
+ fields = fields ,
198
+ headers = headers ,
199
+ preload_content = preload_content ,
200
+ decode_content = decode_content ,
201
+ redirect = redirect ,
202
+ retries = retries ,
203
+ timeout = timeout ,
204
+ json = json ,
205
+ )
206
+
207
+
208
+ if sys .platform == "emscripten" :
209
+ from .contrib .emscripten import inject_into_urllib3 # noqa: 401
210
+
211
+ inject_into_urllib3 ()
0 commit comments