From c3089168d006bfbf8d383c1c07971d303c5667dd Mon Sep 17 00:00:00 2001 From: "Stephen C. Pope" Date: Wed, 12 Jun 2024 11:50:12 -0600 Subject: [PATCH] Devex: Update python deps (#12590) GitOrigin-RevId: 368855270db64430dd782d96423efaa557472541 --- descarteslabs/core/common/http/session.py | 80 +++++++++++++++++++++++ setup.py | 2 +- 2 files changed, 81 insertions(+), 1 deletion(-) diff --git a/descarteslabs/core/common/http/session.py b/descarteslabs/core/common/http/session.py index dfc19eb2..0974d6df 100644 --- a/descarteslabs/core/common/http/session.py +++ b/descarteslabs/core/common/http/session.py @@ -15,6 +15,7 @@ import logging import uuid from http import HTTPStatus +import warnings import requests import requests.adapters @@ -23,6 +24,16 @@ import urllib3 import urllib3.exceptions +try: + from urllib3.contrib.socks import SOCKSProxyManager +except ImportError: + + def SOCKSProxyManager(*args, **kwargs): + raise requests.exceptions.InvalidSchema( + "Missing dependencies for SOCKS support." + ) + + from descarteslabs.exceptions import ( BadRequestError, ConflictError, @@ -145,6 +156,17 @@ def proxy_manager_for(self, proxy, url=None, **proxy_kwargs): if proxy in self.proxy_manager: manager = self.proxy_manager[proxy] + elif proxy.lower().startswith("socks"): + username, password = requests.utils.get_auth_from_url(proxy) + manager = self.proxy_manager[proxy] = SOCKSProxyManager( + proxy, + username=username, + password=password, + num_pools=self._pool_connections, + maxsize=self._pool_maxsize, + block=self._pool_block, + **proxy_kwargs, + ) else: proxy_headers = self.proxy_headers(proxy, url) manager = self.proxy_manager[proxy] = urllib3.poolmanager.proxy_from_url( @@ -158,6 +180,55 @@ def proxy_manager_for(self, proxy, url=None, **proxy_kwargs): return manager + def get_connection_with_tls_context(self, request, verify, proxies=None, cert=None): + """Returns a urllib3 connection for the given request and TLS settings. + This should not be called from user code, and is only exposed for use + when subclassing the :class:`HTTPAdapter `. + + :param request: + The :class:`PreparedRequest ` object to be sent + over the connection. + :param verify: + Either a boolean, in which case it controls whether we verify the + server's TLS certificate, or a string, in which case it must be a + path to a CA bundle to use. + :param proxies: + (optional) The proxies dictionary to apply to the request. + :param cert: + (optional) Any user-provided SSL certificate to be used for client + authentication (a.k.a., mTLS). + :rtype: + urllib3.ConnectionPool + """ + proxy = requests.utils.select_proxy(request.url, proxies) + try: + host_params, pool_kwargs = self.build_connection_pool_key_attributes( + request, + verify, + cert, + ) + except ValueError as e: + raise requests.exceptions.InvalidURL(e, request=request) + if proxy: + proxy = requests.utils.prepend_scheme_if_needed(proxy, "http") + proxy_url = urllib3.util.parse_url(proxy) + if not proxy_url.host: + raise requests.exceptions.InvalidProxyURL( + "Please check proxy URL. It is malformed " + "and could be missing the host." + ) + proxy_manager = self.proxy_manager_for(proxy, request.url) + conn = proxy_manager.connection_from_host( + **host_params, pool_kwargs=pool_kwargs + ) + else: + # Only scheme should be lower case + conn = self.poolmanager.connection_from_host( + **host_params, pool_kwargs=pool_kwargs + ) + + return conn + def get_connection(self, url, proxies=None): """Copied from requests.adapters.HTTPAdapter to pass request url to proxy_manager_for() @@ -169,6 +240,15 @@ def get_connection(self, url, proxies=None): The proxies configured for this request. """ + warnings.warn( + ( + "`get_connection` has been deprecated in favor of " + "`get_connection_with_tls_context`. Custom HTTPAdapter subclasses " + "will need to migrate for Requests>=2.32.2. Please see " + "https://github.com/psf/requests/pull/6710 for more details." + ), + DeprecationWarning, + ) proxy = requests.utils.select_proxy(url, proxies) if proxy: diff --git a/setup.py b/setup.py index 7dc874e4..6d865c7d 100644 --- a/setup.py +++ b/setup.py @@ -109,7 +109,7 @@ def do_setup(): "pyarrow>=14.0.1", "pydantic>=2.1.0", "pytz>=2021.1", - "requests>=2.31.0,<3", + "requests>=2.32.3,<3", # It is not obvious but dynaconf requires pkg_resources from setuptools. "setuptools>=65.6.3", "shapely>=2.0.0",