Skip to content

Commit 359f203

Browse files
committed
python: reinstate no_proxy support
1 parent 5677f5b commit 359f203

File tree

3 files changed

+81
-1
lines changed

3 files changed

+81
-1
lines changed

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 = None
417+
"""bypass proxy for host in the no_proxy list.
418+
"""
416419
self.proxy_headers = None
417420
"""Proxy headers
418421
"""

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

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,12 @@
33
{{>partial_header}}
44

55
import io
6+
import ipaddress
67
import json
78
import re
89
import ssl
10+
from urllib.parse import urlparse
11+
from urllib.request import proxy_bypass_environment
912

1013
import urllib3
1114

@@ -89,7 +92,7 @@ class RESTClientObject:
8992
# https pool manager
9093
self.pool_manager: urllib3.PoolManager
9194

92-
if configuration.proxy:
95+
if configuration.proxy and not should_bypass_proxies(configuration.host, no_proxy=configuration.no_proxy or ''):
9396
if is_socks_proxy_url(configuration.proxy):
9497
from urllib3.contrib.socks import SOCKSProxyManager
9598
pool_args["proxy_url"] = configuration.proxy
@@ -246,3 +249,54 @@ class RESTClientObject:
246249
raise ApiException(status=0, reason=msg)
247250

248251
return RESTResponse(r)
252+
253+
def is_ipv4(target):
254+
""" Test if IPv4 address or not
255+
"""
256+
try:
257+
chk = ipaddress.IPv4Address(target)
258+
return True
259+
except ipaddress.AddressValueError:
260+
return False
261+
262+
def in_ipv4net(target, net):
263+
""" Test if target belongs to given IPv4 network
264+
"""
265+
try:
266+
nw = ipaddress.IPv4Network(net)
267+
ip = ipaddress.IPv4Address(target)
268+
if ip in nw:
269+
return True
270+
return False
271+
except ipaddress.AddressValueError:
272+
return False
273+
except ipaddress.NetmaskValueError:
274+
return False
275+
276+
def should_bypass_proxies(url, no_proxy=None):
277+
""" Yet another requests.should_bypass_proxies
278+
Test if proxies should not be used for a particular url.
279+
"""
280+
281+
parsed = urlparse(url)
282+
283+
# special cases
284+
if parsed.hostname in [None, '']:
285+
return True
286+
287+
# special cases
288+
if no_proxy in [None , '']:
289+
return False
290+
if no_proxy == '*':
291+
return True
292+
293+
no_proxy = no_proxy.lower().replace(' ','');
294+
entries = (
295+
host for host in no_proxy.split(',') if host
296+
)
297+
298+
if is_ipv4(parsed.hostname):
299+
for item in entries:
300+
if in_ipv4net(parsed.hostname, item):
301+
return True
302+
return proxy_bypass_environment(parsed.hostname, {'no': no_proxy} )

modules/openapi-generator/src/test/java/org/openapitools/codegen/python/PythonClientCodegenTest.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import io.swagger.v3.parser.core.models.ParseOptions;
2626
import io.swagger.v3.parser.util.SchemaTypeUtil;
2727
import org.openapitools.codegen.*;
28+
import org.openapitools.codegen.config.CodegenConfigurator;
2829
import org.openapitools.codegen.languages.PythonClientCodegen;
2930
import org.openapitools.codegen.languages.features.CXFServerFeatures;
3031
import org.testng.Assert;
@@ -611,4 +612,26 @@ public void testInitFileImportsExports() throws IOException {
611612
assertFileContains(initFilePath, "from openapi_client.models.tag import Tag as Tag");
612613
assertFileContains(initFilePath, "from openapi_client.models.user import User as User");
613614
}
615+
616+
@Test(description = "tests NoProxyPyClient")
617+
public void testNoProxyPyClient() throws Exception {
618+
619+
final String gen = "python";
620+
final String spec = "src/test/resources/3_0/petstore.yaml";
621+
622+
File output = Files.createTempDirectory("test").toFile();
623+
final CodegenConfigurator configurator = new CodegenConfigurator()
624+
.setGeneratorName(gen)
625+
.setInputSpec(spec)
626+
.setOutputDir(output.getAbsolutePath().replace("\\", "/"));
627+
final ClientOptInput clientOptInput = configurator.toClientOptInput();
628+
DefaultGenerator generator = new DefaultGenerator();
629+
List<File> files = generator.opts(clientOptInput).generate();
630+
631+
for (String f : new String[] { "openapi_client/configuration.py", "openapi_client/rest.py" } ) {
632+
TestUtils.ensureContainsFile(files, output, f);
633+
Path p = output.toPath().resolve(f);
634+
TestUtils.assertFileContains(p, "no_proxy");
635+
}
636+
}
614637
}

0 commit comments

Comments
 (0)