11"""
22Python HTTP library with thread-safe connection pooling, file post support, user friendly, and more
33"""
4- from __future__ import absolute_import
4+
5+ from __future__ import annotations
56
67# Set default logging handler to avoid "No handler found" warnings.
78import logging
9+ import sys
10+ import typing
811import warnings
912from logging import NullHandler
1013
1114from . import exceptions
15+ from ._base_connection import _TYPE_BODY
16+ from ._collections import HTTPHeaderDict
1217from ._version import __version__
1318from .connectionpool import HTTPConnectionPool , HTTPSConnectionPool , connection_from_url
14- from .filepost import encode_multipart_formdata
19+ from .filepost import _TYPE_FIELDS , encode_multipart_formdata
1520from .poolmanager import PoolManager , ProxyManager , proxy_from_url
16- from .response import HTTPResponse
21+ from .response import BaseHTTPResponse , HTTPResponse
1722from .util .request import make_headers
1823from .util .retry import Retry
1924from .util .timeout import Timeout
20- from .util .url import get_host
2125
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.
2629try :
27- import urllib3_secure_extra # type: ignore # noqa: F401
30+ import ssl
2831except ImportError :
2932 pass
3033else :
31- warnings .warn (
32- "'urllib3[secure]' extra is deprecated and will be removed "
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+ )
3847
3948__author__ = "Andrey Petrov (andrey.petrov@shazow.net)"
4049__license__ = "MIT"
4150__version__ = __version__
4251
4352__all__ = (
4453 "HTTPConnectionPool" ,
54+ "HTTPHeaderDict" ,
4555 "HTTPSConnectionPool" ,
4656 "PoolManager" ,
4757 "ProxyManager" ,
5262 "connection_from_url" ,
5363 "disable_warnings" ,
5464 "encode_multipart_formdata" ,
55- "get_host" ,
5665 "make_headers" ,
5766 "proxy_from_url" ,
67+ "request" ,
68+ "BaseHTTPResponse" ,
5869)
5970
6071logging .getLogger (__name__ ).addHandler (NullHandler ())
6172
6273
63- def add_stderr_logger (level = logging .DEBUG ):
74+ def add_stderr_logger (
75+ level : int = logging .DEBUG ,
76+ ) -> logging .StreamHandler [typing .TextIO ]:
6477 """
6578 Helper for quickly adding a StreamHandler to the logger. Useful for
6679 debugging.
@@ -87,16 +100,112 @@ def add_stderr_logger(level=logging.DEBUG):
87100# mechanisms to silence them.
88101# SecurityWarning's always go off by default.
89102warnings .simplefilter ("always" , exceptions .SecurityWarning , append = True )
90- # SubjectAltNameWarning's should go off once per host
91- warnings .simplefilter ("default" , exceptions .SubjectAltNameWarning , append = True )
92103# InsecurePlatformWarning's don't vary between requests, so we keep it default.
93104warnings .simplefilter ("default" , exceptions .InsecurePlatformWarning , append = True )
94- # SNIMissingWarnings should go off only once.
95- warnings .simplefilter ("default" , exceptions .SNIMissingWarning , append = True )
96105
97106
98- def disable_warnings (category = exceptions .HTTPWarning ):
107+ def disable_warnings (category : type [ Warning ] = exceptions .HTTPWarning ) -> None :
99108 """
100109 Helper for quickly disabling all urllib3 warnings.
101110 """
102111 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