Reputation: 1325
I'm trying to see if a key called 'AccessKeyId' exists in the output of a boto3 command.
I am getting this error:
File "aws_iam_rotate_keys.py", line 76, in delete_access_key
key2 = response['AccessKeyMetadata'][1]['AccessKeyId']
IndexError: list index out of range
This is the code that generates the error:
user_name = str(input("Enter a user name: "))
paginator = client.get_paginator('list_access_keys')
for response in paginator.paginate(UserName=user_name):
print("Raw response: ", response)
if 'AccessKeyId' and 'AccessKeyMetadata[0]':
key1 = response['AccessKeyMetadata'][0]['AccessKeyId']
print("Key 1: ", key1)
if 'AccessKeyId' and 'AccessKeyMetadata[1]':
key2 = response['AccessKeyMetadata'][1]['AccessKeyId']
This is the contents of a 'response':
{'AccessKeyMetadata': [{'UserName': 'bluethundr', 'AccessKeyId': 'AKIAJNYZQ2U5LGE6ZRWQ', 'Status': 'Active', 'CreateDate': datetime.datetime(2019, 3, 25, 17, 33, 40, tzinfo=tzutc())}], 'IsTruncated': False, 'ResponseMetadata': {'RequestId': '6b3e8952-4f27-11e9-af5a-356bad8d4700', 'HTTPStatusCode': 200, 'HTTPHeaders': {'x-amzn-requestid': '6b3e8952-4f27-11e9-af5a-356bad8d4700', 'content-type': 'text/xml', 'content-length': '558', 'date': 'Mon, 25 Mar 2019 17:57:13 GMT'}, 'RetryAttempts': 0}}
What am I doing wrong? How can I perform this if test correctly?
In this response there can be either one or 2 keys. I want to write an if test that covers both possibilities.
If there are 2 keys the response looks like this and the code doesn't break:
{'AccessKeyMetadata': [{'UserName': 'bluethundr', 'AccessKeyId': 'AKIAJNYZQ2U5LGE6ZRWQ', 'Status': 'Active', 'CreateDate': datetime.datetime(2019, 3, 25, 17, 33, 40, tzinfo=tzutc())}, {'UserName': 'bluethundr', 'AccessKeyId': 'AKIAJVNDVTUVFZHWSRSA', 'Status': 'Active', 'CreateDate': datetime.datetime(2019, 3, 25, 18, 8, 51, tzinfo=tzutc())}], 'IsTruncated': False, 'ResponseMetadata': {'RequestId': '16957e66-4f29-11e9-b7dc-7fcb6d606368', 'HTTPStatusCode': 200, 'HTTPHeaders': {'x-amzn-requestid': '16957e66-4f29-11e9-b7dc-7fcb6d606368', 'content-type': 'text/xml', 'content-length': '771', 'date': 'Mon, 25 Mar 2019 18:09:09 GMT'}, 'RetryAttempts': 0}}
Upvotes: 1
Views: 390
Reputation: 1188
Your checks in the if
clauses are a bit confusing. You're checking for a non-empty string, which will always return True
.
To keep it as close as possible to your current code, here's how you should do it:
user_name = str(input("Enter a user name: "))
paginator = client.get_paginator('list_access_keys')
for response in paginator.paginate(UserName=user_name):
print("Raw response: ", response)
if len(response['AccessKeyMetadata']) and 'AccessKeyId' in response['AccessKeyMetadata'][0].keys():
key1 = response['AccessKeyMetadata'][0]['AccessKeyId']
print("Key 1: ", key1)
if len(response['AccessKeyMetadata']) > 1 and 'AccessKeyId' in response['AccessKeyMetadata'][1].keys():
key2 = response['AccessKeyMetadata'][1]['AccessKeyId']
Upvotes: 1
Reputation: 16666
Your check
if 'AccessKeyId' and 'AccessKeyMetadata[0]':
is a check that simply tests these constant strings. Running this code in the console returns:
>>> 'AccessKeyId' and 'AccessKeyMetadata[0]'
'AccessKeyMetadata[0]'
I suppose you want to test the response object instead:
# if response is a string and not yet parsed:
# response = json.loads(response)
# if it is already parsed, go on
# .get() with a default return value [] won't raise a KeyError
# or check with:
# if 'AccessKeyMetadata' in response
meta_data = response.get('AccessKeyMetadata', [])
if len(meta_data) == 1:
key1 = meta_data[0].get('AccessKeyId', None)
elif len(meta_data) > 1:
key2 = meta_data[1].get('AccessKeyId', None)
Upvotes: 2
Reputation: 160
Your if-statements are not doing what you think they're doing. For example:
if 'AccessKeyMetadata'
should be:
if response['AccessKeyMetadata']
Upvotes: 0
Reputation: 33335
In that response, AccessKeyMetadata
is a list of one item, therefore index 1 is out of range.
Upvotes: 0