@@ -110,47 +110,98 @@ def __init__(
110
110
Raises:
111
111
ValueError: If region_name parameter conflicts with boto3_session region.
112
112
"""
113
+ # Initialize core attributes
114
+ self ._memory_id = memory_id
115
+
116
+ # Setup session and validate region consistency
113
117
session = boto3_session if boto3_session else boto3 .Session ()
118
+ self .region_name = self ._validate_and_resolve_region (region_name , session )
119
+
120
+ # Configure and create boto3 client
121
+ client_config = self ._build_client_config (boto_client_config )
122
+ self ._data_plane_client = session .client (
123
+ "bedrock-agentcore" , region_name = self .region_name , config = client_config
124
+ )
125
+
126
+ # Configure timestamp serialization for microsecond precision
127
+ self ._configure_timestamp_serialization ()
128
+
129
+ # Define allowed data plane methods
130
+ self ._ALLOWED_DATA_PLANE_METHODS = {
131
+ "retrieve_memory_records" ,
132
+ "get_memory_record" ,
133
+ "delete_memory_record" ,
134
+ "list_memory_records" ,
135
+ "create_event" ,
136
+ "get_event" ,
137
+ "delete_event" ,
138
+ "list_events" ,
139
+ }
140
+
141
+ def _validate_and_resolve_region (self , region_name : Optional [str ], session : boto3 .Session ) -> str :
142
+ """Validate region consistency and resolve the final region to use.
143
+
144
+ Args:
145
+ region_name: Explicitly provided region name
146
+ session: Boto3 session instance
147
+
148
+ Returns:
149
+ The resolved region name to use
150
+
151
+ Raises:
152
+ ValueError: If region_name conflicts with session region
153
+ """
114
154
session_region = session .region_name
115
155
116
156
# Validate region consistency if both are provided
117
- if region_name and boto3_session and session_region and region_name != session_region :
157
+ if region_name and session_region and isinstance ( session_region , str ) and region_name != session_region :
118
158
raise ValueError (
119
159
f"Region mismatch: provided region_name '{ region_name } ' does not match "
120
160
f"boto3_session region '{ session_region } '. Please ensure both "
121
161
f"parameters specify the same region or omit the region_name parameter "
122
162
f"to use the session's region."
123
163
)
124
164
125
- # Configure boto3 client with merged configuration
165
+ return region_name or session_region
166
+
167
+ def _build_client_config (self , boto_client_config : Optional [BotocoreConfig ]) -> BotocoreConfig :
168
+ """Build the final boto3 client configuration with SDK user agent.
169
+
170
+ Args:
171
+ boto_client_config: Optional user-provided client configuration
172
+
173
+ Returns:
174
+ Final client configuration with SDK user agent
175
+ """
176
+ sdk_user_agent = "bedrock-agentcore-sdk"
177
+
126
178
if boto_client_config :
127
179
existing_user_agent = getattr (boto_client_config , "user_agent_extra" , None )
128
180
if existing_user_agent :
129
- new_user_agent = f"{ existing_user_agent } bedrock-agentcore-sdk "
181
+ new_user_agent = f"{ existing_user_agent } { sdk_user_agent } "
130
182
else :
131
- new_user_agent = "bedrock-agentcore-sdk"
132
- client_config = boto_client_config .merge (BotocoreConfig (user_agent_extra = new_user_agent ))
183
+ new_user_agent = sdk_user_agent
184
+ return boto_client_config .merge (BotocoreConfig (user_agent_extra = new_user_agent ))
133
185
else :
134
- client_config = BotocoreConfig (user_agent_extra = "bedrock-agentcore-sdk" )
186
+ return BotocoreConfig (user_agent_extra = sdk_user_agent )
135
187
136
- # Use provided region_name or fall back to session region
137
- self .region_name = region_name or session_region
138
- self ._memory_id = memory_id
139
- self ._data_plane_client = session .client (
140
- "bedrock-agentcore" , region_name = self .region_name , config = client_config
141
- )
188
+ def _configure_timestamp_serialization (self ) -> None :
189
+ """Configure the boto3 client to serialize timestamps with microsecond precision.
142
190
143
- # AgentCore Memory data plane methods
144
- self ._ALLOWED_DATA_PLANE_METHODS = {
145
- "retrieve_memory_records" ,
146
- "get_memory_record" ,
147
- "delete_memory_record" ,
148
- "list_memory_records" ,
149
- "create_event" ,
150
- "get_event" ,
151
- "delete_event" ,
152
- "list_events" ,
153
- }
191
+ This method overrides the default timestamp serialization to preserve microsecond
192
+ precision when sending datetime objects to the AgentCore Memory service.
193
+ """
194
+ original_serialize_timestamp = self ._data_plane_client ._serializer ._serializer ._serialize_type_timestamp
195
+
196
+ def serialize_timestamp_with_microseconds (serialized , value , shape , name ):
197
+ if isinstance (value , datetime ):
198
+ serialized [name ] = value .timestamp () # Float with microseconds
199
+ else :
200
+ original_serialize_timestamp (serialized , value , shape , name )
201
+
202
+ self ._data_plane_client ._serializer ._serializer ._serialize_type_timestamp = (
203
+ serialize_timestamp_with_microseconds
204
+ )
154
205
155
206
def __getattr__ (self , name : str ):
156
207
"""Dynamically forward method calls to the appropriate boto3 client.
0 commit comments