Skip to content

[python] Support proxy_ssl_context for the urllib3-based client - #24539

Open
emmanuel-adu wants to merge 4 commits into
OpenAPITools:masterfrom
emmanuel-adu:feat/urllib3-proxy-ssl-context
Open

[python] Support proxy_ssl_context for the urllib3-based client#24539
emmanuel-adu wants to merge 4 commits into
OpenAPITools:masterfrom
emmanuel-adu:feat/urllib3-proxy-ssl-context

Conversation

@emmanuel-adu

@emmanuel-adu emmanuel-adu commented Jul 31, 2026

Copy link
Copy Markdown

Description

Adds Configuration.proxy_ssl_context (default None, no behavior change) so callers can supply an SSL context used only for the TLS handshake with an HTTPS proxy, independent of the destination TLS settings. This maps directly to urllib3's own proxy_ssl_context support in ProxyManager.

Applies to the python (urllib3 library) and python-pydantic-v1 generators. Not applicable to the SOCKS proxy path (no TLS handshake against a SOCKS proxy) or to the aiohttp-based async client (doesn't use urllib3's ProxyManager).

Context: came up in kubernetes-client/python#2658, where this was requested to live in the upstream generator rather than as a post-processing patch downstream.

cc @cbornet @tomplus @krjakbrjak @fa0311 (Python technical committee)

PR checklist

  • Read the contribution guidelines.
  • Ran ./mvnw clean package, ./bin/generate-samples.sh ./bin/configs/python*.yaml, and ./bin/utils/export_docs_generators.sh (no doc diff, since this isn't a CLI/codegen option). All changed samples are committed.
  • Mentioned the Python technical committee above.

Summary by cubic

Adds Configuration.proxy_ssl_context to the urllib3 Python client and forwards it to ProxyManager for HTTPS proxy TLS handshakes.

Defaults to None; only applies to urllib3 (not SOCKS/aiohttp/tornado); fixes Configuration.__deepcopy__ for ssl.SSLContext while preserving generator behavior; bumps python-pydantic-v1 urllib3 floor to >=1.26.0.

Written for commit b0ed61c. Summary will update on new commits.

Review in cubic

Adds an optional Configuration.proxy_ssl_context so callers can supply a
distinct SSL context for the TLS handshake with an HTTPS proxy, separate
from the destination (API server) TLS settings, per urllib3's
proxy_ssl_context support. Defaults to None (no behavior change).

Applies to the python (urllib3 library) and python-pydantic-v1 generators.
Not applicable to the SOCKS proxy path (no TLS handshake with a SOCKS
proxy) or to the aiohttp-based async client (does not use urllib3's
ProxyManager).

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 19 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="samples/client/echo_api/python-pydantic-v1/openapi_client/rest.py">

<violation number="1" location="samples/client/echo_api/python-pydantic-v1/openapi_client/rest.py:110">
P1: Clients resolved to supported urllib3 1.25.x fail when callers set this option, because that release does not implement `ProxyManager.proxy_ssl_context`. Raise the generated urllib3 minimum to 1.26.0 (including all package metadata/templates), or guard/reject the option for older versions.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

)
else:
if configuration.proxy_ssl_context is not None:
addition_pool_args['proxy_ssl_context'] = configuration.proxy_ssl_context

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: Clients resolved to supported urllib3 1.25.x fail when callers set this option, because that release does not implement ProxyManager.proxy_ssl_context. Raise the generated urllib3 minimum to 1.26.0 (including all package metadata/templates), or guard/reject the option for older versions.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At samples/client/echo_api/python-pydantic-v1/openapi_client/rest.py, line 110:

<comment>Clients resolved to supported urllib3 1.25.x fail when callers set this option, because that release does not implement `ProxyManager.proxy_ssl_context`. Raise the generated urllib3 minimum to 1.26.0 (including all package metadata/templates), or guard/reject the option for older versions.</comment>

<file context>
@@ -106,6 +106,8 @@ def __init__(self, configuration, pools_size=4, maxsize=None) -> None:
                     )
             else:
+                if configuration.proxy_ssl_context is not None:
+                    addition_pool_args['proxy_ssl_context'] = configuration.proxy_ssl_context
                 self.pool_manager = urllib3.ProxyManager(
                     num_pools=pools_size,
</file context>

- Configuration.__deepcopy__ special-cases proxy_ssl_context (like the
  existing retries/proxy_headers handling), since ssl.SSLContext cannot
  be deep-copied and previously raised TypeError.
- Gate proxy_ssl_context to the true urllib3 library variant only (not
  asyncio/aiohttp, not the deprecated tornado library), since neither
  of those REST clients read the option.
- Raise python-pydantic-v1's generated urllib3 floor from 1.25.3 to
  1.26.0, the version that added ProxyManager's proxy_ssl_context
  kwarg, so setting the option can't crash under an allowed-but-too-old
  urllib3.
@emmanuel-adu

emmanuel-adu commented Jul 31, 2026

Copy link
Copy Markdown
Author

Addressed all 7 findings in 2a30617:

  • Deepcopy crash (P1/P2, 3 occurrences): `Configuration.deepcopy` now special-cases `proxy_ssl_context` the same way `retries`/`proxy_headers` already are - assign by reference instead of deep-copying, since `ssl.SSLContext` can't be pickled/deepcopied. Verified the fix directly: `copy.deepcopy(config)` with `proxy_ssl_context` set used to raise `TypeError: cannot pickle 'SSLContext' object`; now succeeds and preserves the same context object by reference.
  • urllib3 floor too low for python-pydantic-v1 (P1): bumped the generated `urllib3` minimum from `1.25.3` to `1.26.0` (requirements.txt, setup.py, pyproject.toml, README) - confirmed `1.26.0` is the exact release that added `ProxyManager.proxy_ssl_context`.
  • Tornado exposes a dead option (P3): gated `proxy_ssl_context` to the true `urllib3` library variant only (excluded for both `tornado` and `asyncio`/`httpx`), since none of those REST clients read it. Verified with an ad-hoc `--library tornado` generation that the option and its `ssl` import no longer appear.
  • pydantic-v1-aiohttp dead code (P3): same gating applied to `python-pydantic-v1/configuration.mustache`.

All samples regenerated via `./bin/generate-samples.sh ./bin/configs/python*.yaml` and `./bin/utils/export_docs_generators.sh` (no doc diff, as expected).

@wing328

wing328 commented Jul 31, 2026

Copy link
Copy Markdown
Member

thanks for the pr

please review the build errors when you've time

My previous restructuring of the non-useIndependentImplicitClients
__deepcopy__ branch (if k in (...): continue / setattr(...)) changed
the exact generated line
    if k not in ('logger', 'logger_file_handler'):
that PythonClientCodegenTest.testIndependentImplicitClientsPreserveDefaultsWhenDisabled
asserts on verbatim, breaking CI on all 3 Java build jobs.

Restore that literal line unchanged and instead insert the
proxy_ssl_context special-case as an early continue before it, which
is behavior-identical and a smaller diff. Verified locally: the
previously-failing PythonClientCodegenTest now passes (62/62), and the
proxy_ssl_context deepcopy fix still works end-to-end.
@emmanuel-adu

Copy link
Copy Markdown
Author

thanks for the pr

please review the build errors when you've time

@wing328 addressed build error

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants