1+ import ssl
2+ import urllib .parse
3+ import urllib .request
4+ from typing import Dict , Any , Optional , Tuple , Union
5+
6+ from urllib3 import HTTPConnectionPool , HTTPSConnectionPool , ProxyManager
7+ from urllib3 .util import make_headers
8+
9+ from databricks .sql .auth .retry import DatabricksRetryPolicy
10+ from databricks .sql .types import SSLOptions
11+
12+ def detect_and_parse_proxy (
13+ scheme : str , host : str
14+ ) -> Tuple [Optional [str ], Optional [Dict [str , str ]]]:
15+ """
16+ Detect system proxy and return proxy URI and headers using standardized logic.
17+
18+ Args:
19+ scheme: URL scheme (http/https)
20+ host: Target hostname
21+
22+ Returns:
23+ Tuple of (proxy_uri, proxy_headers) or (None, None) if no proxy
24+ """
25+ try :
26+ # returns a dictionary of scheme -> proxy server URL mappings.
27+ # https://docs.python.org/3/library/urllib.request.html#urllib.request.getproxies
28+ proxy = urllib .request .getproxies ().get (scheme )
29+ except (KeyError , AttributeError ):
30+ # No proxy found or getproxies() failed - disable proxy
31+ proxy = None
32+ else :
33+ # Proxy found, but check if this host should bypass proxy
34+ if host and urllib .request .proxy_bypass (host ):
35+ proxy = None # Host bypasses proxy per system rules
36+
37+ if not proxy :
38+ return None , None
39+
40+ parsed_proxy = urllib .parse .urlparse (proxy )
41+ proxy_headers = create_basic_proxy_auth_headers (parsed_proxy )
42+ return proxy , proxy_headers
43+
44+
45+ def create_basic_proxy_auth_headers (parsed_proxy ) -> Optional [Dict [str , str ]]:
46+ """
47+ Create basic auth headers for proxy if credentials are provided.
48+
49+ Args:
50+ parsed_proxy: Parsed proxy URL from urllib.parse.urlparse()
51+
52+ Returns:
53+ Dictionary of proxy auth headers or None if no credentials
54+ """
55+ if parsed_proxy is None or not parsed_proxy .username :
56+ return None
57+ ap = f"{ urllib .parse .unquote (parsed_proxy .username )} :{ urllib .parse .unquote (parsed_proxy .password )} "
58+ return make_headers (proxy_basic_auth = ap )
0 commit comments