You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			212 lines
		
	
	
		
			6.8 KiB
		
	
	
	
		
			Python
		
	
			
		
		
	
	
			212 lines
		
	
	
		
			6.8 KiB
		
	
	
	
		
			Python
		
	
"""
 | 
						|
Python HTTP library with thread-safe connection pooling, file post support, user friendly, and more
 | 
						|
"""
 | 
						|
 | 
						|
from __future__ import annotations
 | 
						|
 | 
						|
# Set default logging handler to avoid "No handler found" warnings.
 | 
						|
import logging
 | 
						|
import sys
 | 
						|
import typing
 | 
						|
import warnings
 | 
						|
from logging import NullHandler
 | 
						|
 | 
						|
from . import exceptions
 | 
						|
from ._base_connection import _TYPE_BODY
 | 
						|
from ._collections import HTTPHeaderDict
 | 
						|
from ._version import __version__
 | 
						|
from .connectionpool import HTTPConnectionPool, HTTPSConnectionPool, connection_from_url
 | 
						|
from .filepost import _TYPE_FIELDS, encode_multipart_formdata
 | 
						|
from .poolmanager import PoolManager, ProxyManager, proxy_from_url
 | 
						|
from .response import BaseHTTPResponse, HTTPResponse
 | 
						|
from .util.request import make_headers
 | 
						|
from .util.retry import Retry
 | 
						|
from .util.timeout import Timeout
 | 
						|
 | 
						|
# Ensure that Python is compiled with OpenSSL 1.1.1+
 | 
						|
# If the 'ssl' module isn't available at all that's
 | 
						|
# fine, we only care if the module is available.
 | 
						|
try:
 | 
						|
    import ssl
 | 
						|
except ImportError:
 | 
						|
    pass
 | 
						|
else:
 | 
						|
    if not ssl.OPENSSL_VERSION.startswith("OpenSSL "):  # Defensive:
 | 
						|
        warnings.warn(
 | 
						|
            "urllib3 v2 only supports OpenSSL 1.1.1+, currently "
 | 
						|
            f"the 'ssl' module is compiled with {ssl.OPENSSL_VERSION!r}. "
 | 
						|
            "See: https://github.com/urllib3/urllib3/issues/3020",
 | 
						|
            exceptions.NotOpenSSLWarning,
 | 
						|
        )
 | 
						|
    elif ssl.OPENSSL_VERSION_INFO < (1, 1, 1):  # Defensive:
 | 
						|
        raise ImportError(
 | 
						|
            "urllib3 v2 only supports OpenSSL 1.1.1+, currently "
 | 
						|
            f"the 'ssl' module is compiled with {ssl.OPENSSL_VERSION!r}. "
 | 
						|
            "See: https://github.com/urllib3/urllib3/issues/2168"
 | 
						|
        )
 | 
						|
 | 
						|
__author__ = "Andrey Petrov (andrey.petrov@shazow.net)"
 | 
						|
__license__ = "MIT"
 | 
						|
__version__ = __version__
 | 
						|
 | 
						|
__all__ = (
 | 
						|
    "HTTPConnectionPool",
 | 
						|
    "HTTPHeaderDict",
 | 
						|
    "HTTPSConnectionPool",
 | 
						|
    "PoolManager",
 | 
						|
    "ProxyManager",
 | 
						|
    "HTTPResponse",
 | 
						|
    "Retry",
 | 
						|
    "Timeout",
 | 
						|
    "add_stderr_logger",
 | 
						|
    "connection_from_url",
 | 
						|
    "disable_warnings",
 | 
						|
    "encode_multipart_formdata",
 | 
						|
    "make_headers",
 | 
						|
    "proxy_from_url",
 | 
						|
    "request",
 | 
						|
    "BaseHTTPResponse",
 | 
						|
)
 | 
						|
 | 
						|
logging.getLogger(__name__).addHandler(NullHandler())
 | 
						|
 | 
						|
 | 
						|
def add_stderr_logger(
 | 
						|
    level: int = logging.DEBUG,
 | 
						|
) -> logging.StreamHandler[typing.TextIO]:
 | 
						|
    """
 | 
						|
    Helper for quickly adding a StreamHandler to the logger. Useful for
 | 
						|
    debugging.
 | 
						|
 | 
						|
    Returns the handler after adding it.
 | 
						|
    """
 | 
						|
    # This method needs to be in this __init__.py to get the __name__ correct
 | 
						|
    # even if urllib3 is vendored within another package.
 | 
						|
    logger = logging.getLogger(__name__)
 | 
						|
    handler = logging.StreamHandler()
 | 
						|
    handler.setFormatter(logging.Formatter("%(asctime)s %(levelname)s %(message)s"))
 | 
						|
    logger.addHandler(handler)
 | 
						|
    logger.setLevel(level)
 | 
						|
    logger.debug("Added a stderr logging handler to logger: %s", __name__)
 | 
						|
    return handler
 | 
						|
 | 
						|
 | 
						|
# ... Clean up.
 | 
						|
del NullHandler
 | 
						|
 | 
						|
 | 
						|
# All warning filters *must* be appended unless you're really certain that they
 | 
						|
# shouldn't be: otherwise, it's very hard for users to use most Python
 | 
						|
# mechanisms to silence them.
 | 
						|
# SecurityWarning's always go off by default.
 | 
						|
warnings.simplefilter("always", exceptions.SecurityWarning, append=True)
 | 
						|
# InsecurePlatformWarning's don't vary between requests, so we keep it default.
 | 
						|
warnings.simplefilter("default", exceptions.InsecurePlatformWarning, append=True)
 | 
						|
 | 
						|
 | 
						|
def disable_warnings(category: type[Warning] = exceptions.HTTPWarning) -> None:
 | 
						|
    """
 | 
						|
    Helper for quickly disabling all urllib3 warnings.
 | 
						|
    """
 | 
						|
    warnings.simplefilter("ignore", category)
 | 
						|
 | 
						|
 | 
						|
_DEFAULT_POOL = PoolManager()
 | 
						|
 | 
						|
 | 
						|
def request(
 | 
						|
    method: str,
 | 
						|
    url: str,
 | 
						|
    *,
 | 
						|
    body: _TYPE_BODY | None = None,
 | 
						|
    fields: _TYPE_FIELDS | None = None,
 | 
						|
    headers: typing.Mapping[str, str] | None = None,
 | 
						|
    preload_content: bool | None = True,
 | 
						|
    decode_content: bool | None = True,
 | 
						|
    redirect: bool | None = True,
 | 
						|
    retries: Retry | bool | int | None = None,
 | 
						|
    timeout: Timeout | float | int | None = 3,
 | 
						|
    json: typing.Any | None = None,
 | 
						|
) -> BaseHTTPResponse:
 | 
						|
    """
 | 
						|
    A convenience, top-level request method. It uses a module-global ``PoolManager`` instance.
 | 
						|
    Therefore, its side effects could be shared across dependencies relying on it.
 | 
						|
    To avoid side effects create a new ``PoolManager`` instance and use it instead.
 | 
						|
    The method does not accept low-level ``**urlopen_kw`` keyword arguments.
 | 
						|
 | 
						|
    :param method:
 | 
						|
        HTTP request method (such as GET, POST, PUT, etc.)
 | 
						|
 | 
						|
    :param url:
 | 
						|
        The URL to perform the request on.
 | 
						|
 | 
						|
    :param body:
 | 
						|
        Data to send in the request body, either :class:`str`, :class:`bytes`,
 | 
						|
        an iterable of :class:`str`/:class:`bytes`, or a file-like object.
 | 
						|
 | 
						|
    :param fields:
 | 
						|
        Data to encode and send in the request body.
 | 
						|
 | 
						|
    :param headers:
 | 
						|
        Dictionary of custom headers to send, such as User-Agent,
 | 
						|
        If-None-Match, etc.
 | 
						|
 | 
						|
    :param bool preload_content:
 | 
						|
        If True, the response's body will be preloaded into memory.
 | 
						|
 | 
						|
    :param bool decode_content:
 | 
						|
        If True, will attempt to decode the body based on the
 | 
						|
        'content-encoding' header.
 | 
						|
 | 
						|
    :param redirect:
 | 
						|
        If True, automatically handle redirects (status codes 301, 302,
 | 
						|
        303, 307, 308). Each redirect counts as a retry. Disabling retries
 | 
						|
        will disable redirect, too.
 | 
						|
 | 
						|
    :param retries:
 | 
						|
        Configure the number of retries to allow before raising a
 | 
						|
        :class:`~urllib3.exceptions.MaxRetryError` exception.
 | 
						|
 | 
						|
        If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a
 | 
						|
        :class:`~urllib3.util.retry.Retry` object for fine-grained control
 | 
						|
        over different types of retries.
 | 
						|
        Pass an integer number to retry connection errors that many times,
 | 
						|
        but no other types of errors. Pass zero to never retry.
 | 
						|
 | 
						|
        If ``False``, then retries are disabled and any exception is raised
 | 
						|
        immediately. Also, instead of raising a MaxRetryError on redirects,
 | 
						|
        the redirect response will be returned.
 | 
						|
 | 
						|
    :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int.
 | 
						|
 | 
						|
    :param timeout:
 | 
						|
        If specified, overrides the default timeout for this one
 | 
						|
        request. It may be a float (in seconds) or an instance of
 | 
						|
        :class:`urllib3.util.Timeout`.
 | 
						|
 | 
						|
    :param json:
 | 
						|
        Data to encode and send as JSON with UTF-encoded in the request body.
 | 
						|
        The ``"Content-Type"`` header will be set to ``"application/json"``
 | 
						|
        unless specified otherwise.
 | 
						|
    """
 | 
						|
 | 
						|
    return _DEFAULT_POOL.request(
 | 
						|
        method,
 | 
						|
        url,
 | 
						|
        body=body,
 | 
						|
        fields=fields,
 | 
						|
        headers=headers,
 | 
						|
        preload_content=preload_content,
 | 
						|
        decode_content=decode_content,
 | 
						|
        redirect=redirect,
 | 
						|
        retries=retries,
 | 
						|
        timeout=timeout,
 | 
						|
        json=json,
 | 
						|
    )
 | 
						|
 | 
						|
 | 
						|
if sys.platform == "emscripten":
 | 
						|
    from .contrib.emscripten import inject_into_urllib3  # noqa: 401
 | 
						|
 | 
						|
    inject_into_urllib3()
 |