perf: allow sharing an SSL context across clients - #547
Open
lilyydu wants to merge 4 commits into
Open
Conversation
Every httpx.AsyncClient builds its own ssl.SSLContext, which parses the full CA bundle (~150 certs) from disk at roughly 2.4ms. Client did this unconditionally and ClientOptions had no way to opt out, so callers that construct many clients paid it repeatedly. Add ClientOptions.verify, an optional pre-built ssl.SSLContext that is passed through to httpx and propagated by clone(). Callers build one context per process and reuse it everywhere. An SSLContext is passed rather than a transport deliberately: httpx reuses the context as-is while keeping per-client connection pools and env-based proxy detection, both of which a custom transport would silently disable. Default behaviour is unchanged. verify defaults to None, which maps to httpx's own True. The field is typed Optional[ssl.SSLContext] and does not accept bool, so TLS verification cannot be disabled through it. Note that a cached context is a snapshot of the CA bundle at the time it is built; long-lived processes should rebuild it periodically to pick up CA rotation. This is why it is opt-in rather than the default. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR introduces an opt-in way to reuse a single TLS ssl.SSLContext across many httpx.AsyncClient instances created by the SDK’s Client, reducing repeated CA-bundle parsing overhead for workloads that instantiate many clients.
Changes:
- Added
ClientOptions.verify: Optional[ssl.SSLContext]and threaded it throughClientconstruction andclone(). - Updated
Clientinitialization to pass the provided SSL context through tohttpx. - Added tests asserting the provided SSL context is used, shared across clients, and preserved/overridden across clones.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| packages/common/src/microsoft_teams/common/http/client.py | Adds ClientOptions.verify and wires it into httpx.AsyncClient construction and clone() option merging. |
| packages/common/tests/test_client.py | Adds tests that introspect the underlying httpx transport to verify SSL context reuse and cloning behavior. |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Naming the field `verify` mirrored httpx, which also accepts bool and str there. That made `verify=False` -- the most common Python TLS workaround -- look like valid input, and it would have silently disabled certificate verification. Renaming to `ssl_context` removes the ambiguity rather than guarding against it: the field only ever meant "a pre-built ssl.SSLContext", and `ssl_context=False` is now rejected by the dataclass itself with no runtime type check required. Drops test_verify_rejects_bool, which covered the guard this replaces. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Issue
Every httpx.AsyncClient builds its own ssl.SSLContext, which parses the full CA bundle (~150 certs) from disk at roughly 2.4ms (on Mac). Client did this unconditionally and ClientOptions had no way to opt out, so callers that construct many clients paid it repeatedly.
Implementation
Added ClientOptions.ssl_context, an optional pre-built ssl.SSLContext that is passed through to httpx and propagated by clone(). Callers build one context per process and reuse it everywhere.
An SSLContext is passed rather than a transport deliberately: httpx reuses the context as-is while keeping per-client connection pools and env-based proxy detection, both of which a custom transport would silently disable.
Default behaviour is unchanged. ssl_context defaults to None, which maps to httpx's own True.
Note that a cached context is a snapshot of the CA bundle at the time it is built; long-lived processes should rebuild it periodically to pick up CA rotation. This is why it is opt-in rather than the default.