__init__.py 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. """
  2. Python HTTP library with thread-safe connection pooling, file post support, user friendly, and more
  3. """
  4. from __future__ import annotations
  5. # Set default logging handler to avoid "No handler found" warnings.
  6. import logging
  7. import typing
  8. import warnings
  9. from logging import NullHandler
  10. from . import exceptions
  11. from ._base_connection import _TYPE_BODY
  12. from ._collections import HTTPHeaderDict
  13. from ._version import __version__
  14. from .connectionpool import HTTPConnectionPool, HTTPSConnectionPool, connection_from_url
  15. from .filepost import _TYPE_FIELDS, encode_multipart_formdata
  16. from .poolmanager import PoolManager, ProxyManager, proxy_from_url
  17. from .response import BaseHTTPResponse, HTTPResponse
  18. from .util.request import make_headers
  19. from .util.retry import Retry
  20. from .util.timeout import Timeout
  21. # Ensure that Python is compiled with OpenSSL 1.1.1+
  22. # If the 'ssl' module isn't available at all that's
  23. # fine, we only care if the module is available.
  24. try:
  25. import ssl
  26. except ImportError:
  27. pass
  28. else:
  29. if not ssl.OPENSSL_VERSION.startswith("OpenSSL "): # Defensive:
  30. warnings.warn(
  31. "urllib3 v2 only supports OpenSSL 1.1.1+, currently "
  32. f"the 'ssl' module is compiled with {ssl.OPENSSL_VERSION!r}. "
  33. "See: https://github.com/urllib3/urllib3/issues/3020",
  34. exceptions.NotOpenSSLWarning,
  35. )
  36. elif ssl.OPENSSL_VERSION_INFO < (1, 1, 1): # Defensive:
  37. raise ImportError(
  38. "urllib3 v2 only supports OpenSSL 1.1.1+, currently "
  39. f"the 'ssl' module is compiled with {ssl.OPENSSL_VERSION!r}. "
  40. "See: https://github.com/urllib3/urllib3/issues/2168"
  41. )
  42. __author__ = "Andrey Petrov (andrey.petrov@shazow.net)"
  43. __license__ = "MIT"
  44. __version__ = __version__
  45. __all__ = (
  46. "HTTPConnectionPool",
  47. "HTTPHeaderDict",
  48. "HTTPSConnectionPool",
  49. "PoolManager",
  50. "ProxyManager",
  51. "HTTPResponse",
  52. "Retry",
  53. "Timeout",
  54. "add_stderr_logger",
  55. "connection_from_url",
  56. "disable_warnings",
  57. "encode_multipart_formdata",
  58. "make_headers",
  59. "proxy_from_url",
  60. "request",
  61. "BaseHTTPResponse",
  62. )
  63. logging.getLogger(__name__).addHandler(NullHandler())
  64. def add_stderr_logger(
  65. level: int = logging.DEBUG,
  66. ) -> logging.StreamHandler[typing.TextIO]:
  67. """
  68. Helper for quickly adding a StreamHandler to the logger. Useful for
  69. debugging.
  70. Returns the handler after adding it.
  71. """
  72. # This method needs to be in this __init__.py to get the __name__ correct
  73. # even if urllib3 is vendored within another package.
  74. logger = logging.getLogger(__name__)
  75. handler = logging.StreamHandler()
  76. handler.setFormatter(logging.Formatter("%(asctime)s %(levelname)s %(message)s"))
  77. logger.addHandler(handler)
  78. logger.setLevel(level)
  79. logger.debug("Added a stderr logging handler to logger: %s", __name__)
  80. return handler
  81. # ... Clean up.
  82. del NullHandler
  83. # All warning filters *must* be appended unless you're really certain that they
  84. # shouldn't be: otherwise, it's very hard for users to use most Python
  85. # mechanisms to silence them.
  86. # SecurityWarning's always go off by default.
  87. warnings.simplefilter("always", exceptions.SecurityWarning, append=True)
  88. # InsecurePlatformWarning's don't vary between requests, so we keep it default.
  89. warnings.simplefilter("default", exceptions.InsecurePlatformWarning, append=True)
  90. def disable_warnings(category: type[Warning] = exceptions.HTTPWarning) -> None:
  91. """
  92. Helper for quickly disabling all urllib3 warnings.
  93. """
  94. warnings.simplefilter("ignore", category)
  95. _DEFAULT_POOL = PoolManager()
  96. def request(
  97. method: str,
  98. url: str,
  99. *,
  100. body: _TYPE_BODY | None = None,
  101. fields: _TYPE_FIELDS | None = None,
  102. headers: typing.Mapping[str, str] | None = None,
  103. preload_content: bool | None = True,
  104. decode_content: bool | None = True,
  105. redirect: bool | None = True,
  106. retries: Retry | bool | int | None = None,
  107. timeout: Timeout | float | int | None = 3,
  108. json: typing.Any | None = None,
  109. ) -> BaseHTTPResponse:
  110. """
  111. A convenience, top-level request method. It uses a module-global ``PoolManager`` instance.
  112. Therefore, its side effects could be shared across dependencies relying on it.
  113. To avoid side effects create a new ``PoolManager`` instance and use it instead.
  114. The method does not accept low-level ``**urlopen_kw`` keyword arguments.
  115. """
  116. return _DEFAULT_POOL.request(
  117. method,
  118. url,
  119. body=body,
  120. fields=fields,
  121. headers=headers,
  122. preload_content=preload_content,
  123. decode_content=decode_content,
  124. redirect=redirect,
  125. retries=retries,
  126. timeout=timeout,
  127. json=json,
  128. )