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

area-persistence Session management or checkpointing size/m

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants