Skip to content

feat(session): allow S3SessionManager to reuse a pre-built S3 client#2301

Open
MukundaKatta wants to merge 1 commit into
strands-agents:mainfrom
MukundaKatta:feat-s3-session-manager-accept-prebuilt-client
Open

feat(session): allow S3SessionManager to reuse a pre-built S3 client#2301
MukundaKatta wants to merge 1 commit into
strands-agents:mainfrom
MukundaKatta:feat-s3-session-manager-accept-prebuilt-client

Conversation

@MukundaKatta
Copy link
Copy Markdown

Summary

Adds an optional s3_client keyword argument to S3SessionManager.__init__ so callers can pass a pre-built boto3 S3 client and avoid the per-instance overhead of constructing a fresh boto3.Session and S3 client on every manager creation.

When s3_client is provided, boto_session, boto_client_config, and region_name are ignored (documented in the docstring) and the caller's client is used as-is.

When s3_client is omitted, behavior is unchanged: the manager builds a boto3.Session (using region_name and boto_session) and a client with the strands-agents user-agent tag.

This is a backward-compatible additive change.

Why

Refs #1163. Users instantiating many S3SessionManager instances in the same process (per-agent, per-session-id, etc.) currently pay the cost of boto3.Session(...) and session.client("s3", ...) on every manager. Each session.client(...) call creates a fresh urllib3 connection pool and runs endpoint discovery against AWS.

Passing a single shared S3 client across managers eliminates that overhead and lets callers control credentials, retry config, and custom endpoints (for example, MinIO or LocalStack) without subclassing.

A Strands maintainer (@pgrayy) acknowledged the issue on #1163: "I agree that we should allow for reuse of the session manager instance so that user do not have to reinitialize the underlying client."

Example

Before:

# Each manager constructs its own boto3.Session + S3 client.
mgr_a = S3SessionManager(session_id="a", bucket="b1", region_name="us-east-1")
mgr_b = S3SessionManager(session_id="b", bucket="b1", region_name="us-east-1")
mgr_c = S3SessionManager(session_id="c", bucket="b1", region_name="us-east-1")

After:

import boto3

shared_client = boto3.client("s3", region_name="us-east-1")
mgr_a = S3SessionManager(session_id="a", bucket="b1", s3_client=shared_client)
mgr_b = S3SessionManager(session_id="b", bucket="b1", s3_client=shared_client)
mgr_c = S3SessionManager(session_id="c", bucket="b1", s3_client=shared_client)

Tests

Added four moto-backed tests to tests/strands/session/test_s3_session_manager.py:

  • test_s3_client_kwarg_reuses_supplied_client — supplied client becomes manager.client.
  • test_s3_client_kwarg_ignores_session_and_configboto_session.client is never called when s3_client is set.
  • test_s3_client_kwarg_supports_session_round_trip — end-to-end create + read of a session through a manager built with the new kwarg.
  • test_default_path_still_works — the existing path with no s3_client is unchanged.

Full session/S3 test suite: 50 passed locally.

Test plan

  • pytest tests/strands/session/test_s3_session_manager.py passes
  • Existing callers (no s3_client= argument) get identical behavior
  • When s3_client= is supplied, no boto3.Session is constructed
  • Docstring documents which arguments are ignored when s3_client is supplied

Refs #1163.

Adds a new optional `s3_client` keyword argument to `S3SessionManager`.
When provided, the manager reuses the caller's boto3 S3 client directly
instead of constructing a new `boto3.Session` and S3 client, avoiding
the per-instance HTTP connection pool + endpoint discovery overhead.
Callers also retain full control of the client (credentials, retry
config, custom endpoints).

When `s3_client` is supplied, the existing `boto_session`,
`boto_client_config`, and `region_name` parameters are ignored
(documented in the docstring).

Backward-compatible: callers that do not pass `s3_client` get the
existing behavior unchanged, including the `strands-agents` user-agent
tag on the auto-built client.

Tests added (moto-backed):
  - test_s3_client_kwarg_reuses_supplied_client
  - test_s3_client_kwarg_ignores_session_and_config
  - test_s3_client_kwarg_supports_session_round_trip
  - test_default_path_still_works

Full session/s3 suite: 50 passed.

Refs strands-agents#1163
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant