Skip to content

Commit 2b228c3

Browse files
add utils class
Signed-off-by: Vikrant Puppala <vikrant.puppala@databricks.com>
1 parent 65e89ce commit 2b228c3

File tree

1 file changed

+58
-0
lines changed

1 file changed

+58
-0
lines changed
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
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

Comments
 (0)