| """ |
| Python HTTP library with thread-safe connection pooling, file post support, user friendly, and more |
| """ |
|
|
| from __future__ import annotations |
|
|
| |
| 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 |
|
|
| |
| |
| |
| try: |
| import ssl |
| except ImportError: |
| pass |
| else: |
| if not ssl.OPENSSL_VERSION.startswith("OpenSSL "): |
| 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): |
| 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. |
| """ |
| |
| |
| 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 |
|
|
|
|
| |
| del NullHandler |
|
|
|
|
| |
| |
| |
| |
| warnings.simplefilter("always", exceptions.SecurityWarning, append=True) |
| |
| 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 |
|
|
| inject_into_urllib3() |
|
|