Blog
October 12, 2015 Marie H.

Boto3 Basics

Boto3 Basics

Photo by <a href="https://unsplash.com/@abid_ahmad_shah?utm_source=cloudista&utm_medium=referral" target="_blank" rel="noopener">Abid Shah</a> on <a href="https://unsplash.com/?utm_source=cloudista&utm_medium=referral" target="_blank" rel="noopener">Unsplash</a>

There is little documentation on using the boto3 library to interact with Amazon’s massive library and the documentation that I found seemed to be outdated as I was getting Key and Attribute errors even with copying and pasting directly from documentation; as such I have compiled two of the most basic functionalities one will start out with when building an application around AWS.

It is my hope that this will assist someone who doesn’t have the time to actually dig through the code, documentation and hack away at a solution.

Create an instance

Below we will simply make a Amazon Linux AMI micro instance, note that you will need to pass a SubnetId attribute to the create_instances method in order to create a Amazon Linux AMI; however if you skipped just to the code boto3 will throw an error for you.

#amazon.py
from flask_restful import Resource, Api, request
from flask_jwt import jwt_required
from boto3.session import Session
from botocore.exceptions import ClientError
import boto, boto3


class AmazonCreateEC2(Resource):
    @jwt_required()
    def post(self):
        data = request.get_json(force=True)
        term = data.get('term')
        '''
        DEV: HardCode
        PROD: DB Pull - 2 Way Encrypt
        '''
        session = Session(
                aws_access_key_id='',
                aws_secret_access_key='',
                region_name='us-east-1',
        )
        ec2 = session.resource('ec2')
        ec2_us_east_1 = session.resource('ec2', region_name='us-east-1')
        try:
            data = ec2.create_instances(
                    ImageId='ami-e3106686',
                    MinCount=1,
                    MaxCount=1,
                    InstanceType='t2.micro',
            )
            return {"success": "Created instance", "data": data}
        except ClientError as e:
            return {"error": str(e)}

Get all running instances

And here we will get all running instances running in the us-east-1 region. Fortunately, I manually typed all of those wonderful attributes for you so you get a nice hash of hashes / dict of dicts or whatever the cool kids are saying nowadays (looks up rubyism for HoH)…

class AmazonReadEC2(Resource):
    @jwt_required()
    def get(self):
        session = Session(
                aws_access_key_id='',
                aws_secret_access_key='',
                region_name='us-east-1',
        )
        ec2 = session.resource('ec2')
        instances = ec2.instances.filter(
            Filters=[{'Name': 'instance-state-name', 'Values': ['running']}])
        i_json = {}
        for instance in instances:
            i_json[instance.id] = {
                "ami_launch_index": instance.ami_launch_index,
                "architecture": instance.architecture,
                "client_token": instance.client_token,
                "ebs_optimized": instance.ebs_optimized,
                "hypervisor": instance.hypervisor,
                "iam_instance_profile": instance.iam_instance_profile,
                "image_id": instance.image_id,
                "instance_id": instance.instance_id,
                "instance_lifecycle": instance.instance_lifecycle,
                "instance_type": instance.instance_type,
                "kernel_id": instance.kernel_id,
                "key_name": instance.key_name,
                "launch_time": str(instance.launch_time),
                "monitoring": instance.monitoring,
                "placement": instance.placement,
                "platform": instance.platform,
                "private_dns_name": instance.private_dns_name,
                "private_ip_address": instance.private_ip_address,
                "product_codes": instance.product_codes,
                "public_dns_name": instance.public_dns_name,
                "public_ip_address": instance.public_ip_address,
                "ramdisk_id": instance.ramdisk_id,
                "root_device_name": instance.root_device_name,
                "root_device_type": instance.root_device_type,
                "security_groups": instance.security_groups,
                "source_dest_check": instance.source_dest_check,
                "spot_instance_request_id": instance.spot_instance_request_id,
                "sriov_net_support": instance.sriov_net_support,
                "state": instance.state,
                "state_reason": instance.state_reason,
                "state_transition_reason": instance.state_transition_reason,
                "subnet_id": instance.subnet_id,
                "tags": instance.tags,
                "virtualization_type": instance.virtualization_type,
                "vpc_id": instance.vpc_id,
            }
        return i_json

Check if a key exists in S3

A new addition to this page since the last time I’d updated it. You can try an load the object via the s3 resource and it will throw a 404 error to be catched to test if a key exists in AWS S3

#!/usr/bin/env python
import os
from botocore.exceptions import ClientError
from boto3.session import Session

# Create AWS Session
session = Session(
  aws_access_key_id='123',
  aws_secret_access_key='123',
  region_name='us-east-1',
)
s3 = session.resource('s3')
obj = s3.Object('bucketname', 'thing.txt')
try:
    obj.load()
except ClientError:
    print("Key doesn't exist in bucket")

Well, that’s some features and I hope that helps someone on the way to interfacing with AWS via Python and Boto3.