bluethundr
bluethundr

Reputation: 1345

Handle missing keys in python dictionary

I'm building a list of EC2 instances in Amazon. And I am testing for the existence of keys called PrivateIpAddress and PublicIpAddress in a dictionary. In some cases neither key exists and I get an exception:

-------------------------------------
Instance ID: i-86533615
Type: m4.xlarge
State: stopped
Private IP: 10.1.233.18
Traceback (most recent call last):
  File ".\aws_ec2_list_instances.py", line 43, in <module>
    print(Fore.CYAN + "{0}: {1}".format(key, instance[key]))
KeyError: 'Public IP'

My code says:

for instance in reservation["Instances"]:
if 'PrivateIpAddress' in instance and 'PublicIpAddress' in instance:
    ... do stuff...
elif 'PrivateIpAddress' in instance:
else:
    ...do stuff..

But the last else doesn't catch the problem of an instance not having either a public ip address or a private ip address.

Here is the full code in python: list ec2 instances

Upvotes: 0

Views: 919

Answers (2)

CryptoFool
CryptoFool

Reputation: 23119

I see a fundamental problem in your logic. You're looping through all the instances and building up maps for each of them in ec2info. But each time through the loop, when processing a particular instance, you're looping over all the data in ec2info, including the data added by previous iterations of the loop. I bet you don't really want to do this. I bet you really want to display the attributes for just the instance you're working on.

Here's the key to your problem:

attributes = ['Instance ID', 'Type',
    'State', 'Private IP', 'Launch Time' ]
for instance_id, instance in ec2info.items():

So here, you're iterating over all the maps in ec2info, and yet you're applying a set of 'attributes' that are specific to the one instance you're currently processing. Since in general, per your own code, not all of the maps in ec2info will have all of the same keys, you're getting the error you're getting.

Upvotes: 1

paras chauhan
paras chauhan

Reputation: 787

for instance in reservation.get("Instances", []):
    private_ip_address = instance.get("PrivateIpAddress" , None)
    public_ip_address = instance.get("PublicIpAddress" , None)
    if  private_ip_address and public_ip_address:
    ... do stuff...
    elif private_ip_address:
       ...do stuff.. 
    else:
       ...do stuff..

Try this one

Upvotes: 1

Related Questions