Skip to content

Commit 183ee97

Browse files
committed
python: Read proxies from environment + support no_proxy
1 parent 4402d83 commit 183ee97

2 files changed

Lines changed: 44 additions & 5 deletions

File tree

modules/openapi-generator/src/main/resources/python/configuration.mustache

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,9 @@ conf = {{{packageName}}}.Configuration(
413413
self.proxy: Optional[str] = None
414414
"""Proxy URL
415415
"""
416+
self.no_proxy: Optional[str] = None
417+
"""Hosts for which to bypass the proxy
418+
"""
416419
self.proxy_headers = None
417420
"""Proxy headers
418421
"""

modules/openapi-generator/src/main/resources/python/rest.mustache

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,12 @@ import io
66
import json
77
import re
88
import ssl
9+
from urllib.parse import urlparse
10+
from urllib.request import getproxies, proxy_bypass
911

1012
import urllib3
1113

14+
from {{packageName}}.configuration import Configuration
1215
from {{packageName}}.exceptions import ApiException, ApiValueError
1316

1417
SUPPORTED_SOCKS_PROXIES = {"socks5", "socks5h", "socks4", "socks4a"}
@@ -49,7 +52,7 @@ class RESTResponse(io.IOBase):
4952

5053
class RESTClientObject:
5154

52-
def __init__(self, configuration) -> None:
55+
def __init__(self, configuration: Configuration) -> None:
5356
# urllib3.PoolManager will pass all kw parameters to connectionpool
5457
# https://github.com/shazow/urllib3/blob/f9409436f83aeb79fbaf090181cd81b784f1b8ce/urllib3/poolmanager.py#L75 # noqa: E501
5558
# https://github.com/shazow/urllib3/blob/f9409436f83aeb79fbaf090181cd81b784f1b8ce/urllib3/connectionpool.py#L680 # noqa: E501
@@ -89,14 +92,23 @@ class RESTClientObject:
8992
# https pool manager
9093
self.pool_manager: urllib3.PoolManager
9194

92-
if configuration.proxy:
93-
if is_socks_proxy_url(configuration.proxy):
95+
parsed = urlparse(configuration.host)
96+
proxy = getproxies().get(parsed.scheme) if configuration.proxy is None else configuration.proxy
97+
if proxy:
98+
if configuration.no_proxy is not None:
99+
if _proxy_bypass(parsed.netloc, configuration.no_proxy):
100+
proxy = None
101+
elif proxy_bypass(parsed.netloc):
102+
proxy = None
103+
104+
if proxy:
105+
if is_socks_proxy_url(proxy):
94106
from urllib3.contrib.socks import SOCKSProxyManager
95-
pool_args["proxy_url"] = configuration.proxy
107+
pool_args["proxy_url"] = proxy
96108
pool_args["headers"] = configuration.proxy_headers
97109
self.pool_manager = SOCKSProxyManager(**pool_args)
98110
else:
99-
pool_args["proxy_url"] = configuration.proxy
111+
pool_args["proxy_url"] = proxy
100112
pool_args["proxy_headers"] = configuration.proxy_headers
101113
self.pool_manager = urllib3.ProxyManager(**pool_args)
102114
else:
@@ -246,3 +258,27 @@ class RESTClientObject:
246258
raise ApiException(status=0, reason=msg)
247259

248260
return RESTResponse(r)
261+
262+
# Adapted from urllib.request.proxy_bypass_environment
263+
def _proxy_bypass(netloc: str, no_proxy: str):
264+
if no_proxy == '*':
265+
return True
266+
267+
host = netloc.lower()
268+
if match := re.match(r'(.*):([0-9]*)', host):
269+
hostonly, _port = match.groups()
270+
else:
271+
hostonly = host
272+
273+
for name in no_proxy.split(','):
274+
name = name.strip()
275+
if name:
276+
name = name.lstrip('.')
277+
name = name.lower()
278+
if hostonly == name or host == name:
279+
return True
280+
name = '.' + name
281+
if hostonly.endswith(name) or host.endswith(name):
282+
return True
283+
284+
return False

0 commit comments

Comments
 (0)