Add optional requests session for connection reuse - #1493
Merged
Conversation
Add an optional session (requests.Session) keyword argument, accepted by OAuth2, APIHarnessV2, the legacy APIHarness, and every Service Class, allowing callers to reuse a persistent HTTP connection across login, every API call, token renewal, and logout. Default (no session) behavior is unchanged, FalconPy never closes a caller-provided session, and no global session is introduced.
Davack
requested review from
alhumaw,
crowdstrikedcs and
jshcodes
as code owners
August 3, 2026 12:41
jshcodes
approved these changes
Aug 5, 2026
jshcodes
left a comment
Member
There was a problem hiding this comment.
Thank you for your contribution!! 🙇
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.
feat: Add optional requests session for connection reuse
Adds an optional
session: Optional[requests.Session] = Nonekeyword argument, accepted byOAuth2,APIHarnessV2, the legacyAPIHarness, and every Service Class, allowing callers to reuse a single HTTP connection across login, every API call, token renewal, and logout — instead of opening a new connection for every request.Added
sessionkeyword toOAuth2,UberInterface/APIHarnessV2,ServiceClass/BaseServiceClass, and the legacyAPIHarnessEvery request path funnels through a single chokepoint (
perform_request()in_util/_functions.py), which now dispatches tosession.requestwhen a session is supplied and to the existing module-levelrequests.requestotherwise — so default (no session) behavior is byte-for-byte unchangedsessionis propagated through the same existing pattern already used forproxy/timeout/user_agent(InterfaceConfiguration→FalconInterface→UberInterface/OAuth2→ServiceClass/BaseServiceClass), includingServiceClass.override()custom routesFalconPy never calls
.close()on a caller-provided session; the caller retains full ownership of its lifecycle (e.g. via awith requests.Session() as session:block)No global/module-level session is introduced — session is scoped to the auth object / harness instance the caller constructs
Added
tests/test_session_support.py(18 tests) andtests/test_session_connection_reuse.py(2 tests), both fully mocked / local-only — no live credentials or internet access requiredAdded
util/session_benchmark.py, a local loopback benchmark demonstrating the connection-reuse mechanism without requiring API credentialsAdded
samples/authentication/session_reuse.pyand a corresponding section insamples/authentication/README.mdEnhancement
Updated unit tests
Documentation
Code sample
Unit test coverage
(These files carry substantial pre-existing coverage from the rest of the suite; the numbers above reflect only the two new session-focused test files run in isolation, not full project coverage. Every new branch introduced by this change — session vs. no-session in
perform_request, login/logout with/without session,APIHarnessV2, legacyAPIHarness,ServiceClass.override()— is exercised.)I do not currently have CrowdStrike API credentials available to run the full live-API test suite (
util/run-tests.sh) from this environment. I ran it against placeholder credentials purely to validate that this change introduces no collection/import errors and no new failures: all 577 non-manual tests still collect cleanly, and I diff-checked the full failure set against an unmodifiedmaincheckout under identical placeholder-credential conditions — byte-for-byte identical failures (confirmed on the 8 files most relevant to this change:test_authentications.py,test_authorization.py,test_uber.py,test_uber_api_complete.py,test_service_class.py,test_hosts.py,test_timeout.py,test_result_object.py— 82/82 identical failures, all attributable to the absence of real API responses, not this change). Happy to have a maintainer re-run against live credentials as an extra check.Bandit analysis
$ bandit -r src Test results: No issues identified. Code scanned: Total lines of code: 135632 Total lines skipped (#nosec): 0 Run metrics: Total issues (by severity): Undefined: 0 Low: 0 Medium: 0 High: 0 Total issues (by confidence): Undefined: 0 Low: 0 Medium: 0 High: 0flake8, pylint (10.00/10), and pydocstyle all pass with zero findings against
src/falconpy.Added features and functionality
sessionkeyword argument toOAuth2,APIHarnessV2(viaUberInterface), the legacyAPIHarness, and every Service Class (viaServiceClass/BaseServiceClass) — reuses arequests.Sessionacross login, every API call, token renewal, and logout._util/_functions.py_api_request/_request.py_api_request/_request_connection.py_auth_object/_interface_config.py_auth_object/_falcon_interface.py_auth_object/_uber_interface.pyoauth2.py_util/_service.py_util/_uber.py_service_class/_base_service_class.pyapi_complete/_legacy.pytests/test_session_support.pytests/test_session_connection_reuse.pyIssues resolved
Other
_ngsiem/_session_manager.py), which was the inspiration for exposing this same pattern more broadly. Those numbers come from earlier testing against the live API and aren't reproduced in this PR's CI-equivalent run (no credentials available there). To back that up with something independently reproducible by any reviewer, I addedutil/session_benchmark.py, a local loopback benchmark requiring no credentials or internet access, which produced a real, reproducible 2.18x speedup from connection reuse alone (isolating the TCP-handshake-avoidance mechanism, without TLS or real network latency, so it understates the live-API improvement):session=) is unchanged — verified explicitly inTestSessionDefaultBehaviorUnchanged, which asserts the module-levelrequests.requestis still used andrequests.Sessionis never instantiated internally when the keyword is omitted.Sessionwas considered and rejected — it would silently change behavior for every existing caller (connection pooling, cookie persistence,trust_envinteractions). Making this strictly opt-in with an unchanged default is the more conservative and appropriate choice for a widely-used SDK.SessionManager, and this PR makes the same capability available generically across the SDK's main request path, opt-in and fully backward compatible.