Skip to content

Commit 1e8fa85

Browse files
fix: replace colorama with rich's native styling in use_aws tool (strands-agents#118)
* fix: replace colorama with rich's native styling in use_aws tool - Replace colorama Fore/Style with rich Table for better UI rendering - Add structured table layout for AWS operation details - Improve visual consistency with other rich-based tools - Remove colorama dependency from use_aws module - Fixes strands-agents#35: use_aws tool rich UI rendering issues * chore: remove colorama dependency from pyproject.toml - No longer needed after replacing colorama with Rich native styling - Fixes Rich panel border rendering issues when mixing ANSI sequences - Part of use-aws Rich UI rendering improvements --------- Co-authored-by: Strands Agent <217235299+strands-agent@users.noreply.github.com>
1 parent 983ec41 commit 1e8fa85

2 files changed

Lines changed: 25 additions & 24 deletions

File tree

pyproject.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ dependencies = [
3030
"rich>=14.0.0,<15.0.0",
3131
"sympy>=1.12.0,<2.0.0",
3232
"prompt_toolkit>=3.0.51,<4.0.0",
33-
"colorama>=0.4.6,<0.5.0",
3433
"aws_requests_auth>=0.4.3,<0.5.0",
3534
"PyJWT>=2.10.1,<3.0.0",
3635
"dill>=0.4.0,<0.5.0",

src/strands_tools/use_aws.py

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
"""
2-
AWS service integration tool for Strands Agent.
1+
"""AWS service integration tool for Strands Agent.
32
43
This module provides a comprehensive interface to AWS services through boto3,
54
allowing you to invoke any AWS API operation directly from your Strands Agent.
@@ -54,18 +53,16 @@
5453
import boto3
5554
from botocore.exceptions import ParamValidationError, ValidationError
5655
from botocore.response import StreamingBody
57-
from colorama import Fore, Style, init
56+
from rich import box
5857
from rich.panel import Panel
58+
from rich.table import Table
5959
from strands.types.tools import ToolResult, ToolUse
6060

6161
from strands_tools.utils import console_util
6262
from strands_tools.utils.data_util import convert_datetime_to_str
6363
from strands_tools.utils.generate_schema_util import generate_input_schema
6464
from strands_tools.utils.user_input import get_user_input
6565

66-
# Initialize colorama
67-
init(autoreset=True)
68-
6966
logger = logging.getLogger(__name__)
7067

7168
MUTATIVE_OPERATIONS = [
@@ -102,8 +99,7 @@ def get_boto3_client(
10299
region_name: str,
103100
profile_name: Optional[str] = None,
104101
) -> Any:
105-
"""
106-
Create an AWS boto3 client for the specified service and region.
102+
"""Create an AWS boto3 client for the specified service and region.
107103
108104
Args:
109105
service_name: Name of the AWS service (e.g., 's3', 'ec2', 'dynamodb')
@@ -118,8 +114,7 @@ def get_boto3_client(
118114

119115

120116
def handle_streaming_body(response: Dict[str, Any]) -> Dict[str, Any]:
121-
"""
122-
Process streaming body responses from AWS into regular Python objects.
117+
"""Process streaming body responses from AWS into regular Python objects.
123118
124119
Some AWS APIs return StreamingBody objects that need special handling to
125120
convert them into regular Python dictionaries or strings for proper JSON serialization.
@@ -141,8 +136,7 @@ def handle_streaming_body(response: Dict[str, Any]) -> Dict[str, Any]:
141136

142137

143138
def get_available_services() -> List[str]:
144-
"""
145-
Get a list of all available AWS services supported by boto3.
139+
"""Get a list of all available AWS services supported by boto3.
146140
147141
Returns:
148142
List of service names as strings
@@ -152,8 +146,7 @@ def get_available_services() -> List[str]:
152146

153147

154148
def get_available_operations(service_name: str) -> List[str]:
155-
"""
156-
Get a list of all available operations for a specific AWS service.
149+
"""Get a list of all available operations for a specific AWS service.
157150
158151
Args:
159152
service_name: Name of the AWS service (e.g., 's3', 'ec2')
@@ -289,14 +282,23 @@ def use_aws(tool: ToolUse, **kwargs: Any) -> ToolResult:
289282

290283
STRANDS_BYPASS_TOOL_CONSENT = os.environ.get("BYPASS_TOOL_CONSENT", "").lower() == "true"
291284

292-
# Create a panel for AWS Operation Details
293-
operation_details = f"{Fore.CYAN}Service:{Style.RESET_ALL} {service_name}\n"
294-
operation_details += f"{Fore.CYAN}Operation:{Style.RESET_ALL} {operation_name}\n"
295-
operation_details += f"{Fore.CYAN}Parameters:{Style.RESET_ALL}\n"
296-
for key, value in parameters.items():
297-
operation_details += f" - {key}: {value}\n"
285+
# Create a panel for AWS Operation Details using Rich's native styling
286+
details_table = Table(show_header=False, box=box.SIMPLE, pad_edge=False)
287+
details_table.add_column("Property", style="cyan", justify="left", min_width=12)
288+
details_table.add_column("Value", style="white", justify="left")
289+
290+
details_table.add_row("Service:", service_name)
291+
details_table.add_row("Operation:", operation_name)
292+
details_table.add_row("Region:", region)
293+
294+
if parameters:
295+
details_table.add_row("Parameters:", "")
296+
for key, value in parameters.items():
297+
details_table.add_row(f" • {key}:", str(value))
298+
else:
299+
details_table.add_row("Parameters:", "None")
298300

299-
console.print(Panel(operation_details, title=label, expand=False))
301+
console.print(Panel(details_table, title=f"[bold blue]🚀 {label}[/bold blue]", border_style="blue", expand=False))
300302

301303
logger.debug(
302304
"Invoking: service_name = %s, operation_name = %s, parameters = %s" % (service_name, operation_name, parameters)
@@ -321,7 +323,7 @@ def use_aws(tool: ToolUse, **kwargs: Any) -> ToolResult:
321323
# Check AWS service
322324
available_services = get_available_services()
323325
if service_name not in available_services:
324-
logger.debug(f"{Fore.RED}Invalid AWS service: {service_name}{Style.RESET_ALL}")
326+
logger.debug(f"Invalid AWS service: {service_name}")
325327
return {
326328
"toolUseId": tool_use_id,
327329
"status": "error",
@@ -333,7 +335,7 @@ def use_aws(tool: ToolUse, **kwargs: Any) -> ToolResult:
333335
# Check AWS operation
334336
available_operations = get_available_operations(service_name)
335337
if operation_name not in available_operations:
336-
logger.debug(f"{Fore.RED}Invalid AWS operation: {operation_name}{Style.RESET_ALL}")
338+
logger.debug(f"Invalid AWS operation: {operation_name}")
337339
return {
338340
"toolUseId": tool_use_id,
339341
"status": "error",

0 commit comments

Comments
 (0)