Boto3

Table of Contents

Concepts

Feature Description
Resources a high level, object oriented interface
Collections a tool to iterate and manipulate groups of resources
Clients low level service connections
Paginators automatic paging of responses
Waiters a way to block until a certain state has been reached

Boto 3 is built atop of a library called Botocore, which is shared by the AWS CLI.

It is recommended to create a resource instance for each thread in a multithreaded application rather than sharing a single instance among the threads

Client vs Resource

import boto3
# Create a low-level client with the service name
sqs = boto3.client('sqs')

# Access client through resource
sqs_resource = boto3.resource('sqs')
sqs = sqs_resource.meta.client
# Entry functions like `boto3.resource`, boto3.client`
# just pass arguments to the default session
def resource(*args, **kwargs):
    return _get_default_session().resource(*args, **kwargs)
boto3.resource('sqs', region_name='ap-northeast1')

Paginators

import boto3

client = boto3.client('s3', region_name='us-west-2')
paginator = client.get_paginator('list_objects')
operation_parameters = {'Bucket': 'my-bucket',
                        'Prefix': 'foo/baz'}
page_iterator = paginator.paginate(**operation_parameters)
for page in page_iterator:
    print(page['Contents'])

Core

client or resource

def client_or_resource(service_name,
                       region_name=None,
                       api_version=None,
                       use_ssl=True,
                       verify=None,
                       endpoint_url=None,
                       aws_access_key_id=None,
                       aws_secret_access_key=None,
                       aws_session_token=None,
                       config=None)
# Access the raw client within a resource
client = resource.meta.client

Waiters

import boto3

s3 = boto3.client('s3')
print('s3 waiters: ', s3.waiter_names)
# [u'bucket_exists', u'bucket_not_exists', u'object_exists', u'object_not_exists']

w = s3.get_waiter('bucket_exists')
w.wait(Bucket='mybucket')

Exceptions

import boto3

try:
    iam = boto3.client('iam')
    user = iam.create_user(UserName='fred')
except iam.exceptions.EntityAlreadyExistsException:
    pass # Handle error here

EC2

# EC2 find instances
ec2 = boto3.resource('ec2')
base = ec2.instances.filter(InstanceIds=['id1', 'id2', 'id3'])

filters = [{
    'name': 'tenancy',
    'value': 'dedicated'
}]
filtered1 = base.filter(Filters=filters)

# Note, this does NOT modify the filters in ``filtered1``!
filters.append({'name': 'instance-type', 'value': 't1.micro'})
filtered2 = base.filter(Filters=filters)

print('All instances:')
for instance in base:
    print(instance.id)

print('Dedicated instances:')
for instance in filtered1:
    print(instance.id)

print('Dedicated micro instances:')
for instance in filtered2:
    print(instance.id)
import boto3

ec2 = boto3.resource('ec2')
instance = ec2.Instance('id')

print instance.private_ip_address  # For more attributes, SEE: EC2.Instance

CloudFormation

import boto3

client = boto3.client('cloudformation')
stack = client.create_stack(StackName='test', TmeplateBody='{"json": "template"}')

# http://boto3.readthedocs.io/en/latest/reference/services/cloudformation.html#CloudFormation.Waiter.StackCreateComplete.wait
waiter = client.get_waiter('stack_create_complete')
waiter.wait(StackName='test', WaiterConfig={'Delay': 5})

DynamoDB

getitem

import boto3

dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('name')

response = table.get_item(Key={'user': user})
{
    'Item': {
        'user': 'yeonghoey',
        'age': 32,
    },
}

query

Query results are always sorted by the sort key value. If the data type of the sort key is Number, the results are returned in numeric order; otherwise, the results are returned in order of UTF-8 bytes. By default, the sort order is ascending. To reverse the order, set the ScanIndexForward parameter to false.

# year - The partition key. The attribute type is number.
# title - The sort key. The attribute type is string.
from boto3.dynamodb.conditions import Key, Attr

# All Movies Released in a Year
response = table.query(
    KeyConditionExpression=Key('year').eq(1985)
)

# All Movies Released in a Year with Certain Titles
# Because 'year' is a reserved keyword, give an alias of '#yr'
response = table.query(
    ProjectionExpression="#yr, title, info.genres, info.actors[0]",
    ExpressionAttributeNames={ "#yr": "year" }, # Expression Attribute Names for Projection Expression only.
    KeyConditionExpression=Key('year').eq(1992) & Key('title').between('A', 'L')
)

print(response['Items'])

ExpressionAttributeNames

{"#P": "Percentile"}

ExpressionAttributeValues

{ ":avail":{"S":"Available"}, ":back":{"S":"Backordered"}, ":disc":{"S":"Discontinued"} }

Links