New Solution:
You can resolve this using Config
from botocore.config
provided by Boto3
, which is an AWS SDK
in Python
, by specifying retry configuration as shown below in the code snippet:
import boto3
from botocore.config import Config
def describe_workspaces():
workspaces_client = boto3.client('workspaces', config=Config(connect_timeout=5, read_timeout=60, retries={'max_attempts': 5}))
return workspaces_client.describe_workspaces()
References:
Old Solution:
You can resolve this using Boto3
, which is an AWS SDK
in Python
, by adding an exception handling for ThrottlingException
and retrying as shown below in the code snippet:
import boto3
from botocore.exceptions import ClientError
def describe_workspaces(tries=1):
try:
return boto3.client('workspaces').describe_workspaces()
except ClientError as exception_obj:
if exception_obj.response['Error']['Code'] == 'ThrottlingException':
if tries <= 3:
print("Throttling Exception Occured.")
print("Retrying.....")
print("Attempt No.: " + str(tries))
time.sleep(3*tries)
return describe_workspaces(tries + 1)
else:
print("Attempted 3 Times But No Success.")
print("Raising Exception.....")
raise
else:
raise
You can create an AWS client
outside the function and can modify the logic as required.
You can handle ThrottlingException
via AWS CLI
as well but it would make more sense if you write some Bash/Shell
script instead of a Python
script. For Python
, Boto3
is recommended.
For more details, check out the following: AWS Workspaces APIs
Generic Old Solution:
If your code has multiple (more than one) AWS client
calls and you don't want to add the same code for ThrottlingException
handling and retrying again and again to each call in order to achieve reusability (DRY; Don't repeat yourself) and avoid unnecessary code repetition, you can use the following code snippet:
import time
import boto3
from botocore.exceptions import ClientError
def generic_aws_client_method(client, method_name, method_arguments, tries=1):
"""Generic AWS client method with throttling exception handling"""
try:
client_method = getattr(client, method_name)
return client_method(**method_arguments)
except ClientError as exception_obj:
if exception_obj.response['Error']['Code'] == 'ThrottlingException':
if tries <= 3:
print("Throttling Exception Occured.")
print("Retrying.....")
print("Attempt No.: " + str(tries))
time.sleep(3*tries)
return generic_aws_client_method(
client,
method_name,
method_arguments,
tries + 1
)
else:
print("Attempted 3 Times But No Success.")
print("Raising Exception.....")
raise
else:
raise
Below you can find some examples on how to use it:
# AWS clients for AWS S3 and AWS SSM respectively
s3_client = boto3.client('s3')
ssm_client = boto3.client('ssm')
# Example 1: With multiple method arguments
mapping = {'Name': '/prod/aws-eks-vpc-id', 'WithDecryption': True}
returned_object = generic_aws_client_method(ssm_client, "get_parameter", mapping)
print(returned_object)
# Example 2: With single method argument
mapping = {'operation_name': 'describe_parameters'}
returned_object = generic_aws_client_method(ssm_client, "get_paginator", mapping)
print(returned_object)
# Example 3: With no method argument
mapping = {}
returned_object = generic_aws_client_method(s3_client, "list_buckets", mapping)
print(returned_object)
Testing ThrottlingException Handling:
In order to test the ThrottlingException
handling in the above code snippets, use the following code snippet to raise a custom ClientError
by yourself:
raise ClientError(
{'Error': {'Code': 'ThrottlingException', 'Message': 'Rate exceeded'}},
'generic_aws_client_method'
)
boto
: boto.readthedocs.org/en/latest – Prolong