Use Resource API rather than Client API in AWS SDK for Python (Boto3)

Introduction

This article is AWS Beginner Advent Calendar 2019 This is the article on the 14th day of. I would appreciate it if you could point out any mistakes.

wrap up

In Boto3, some services have a resource API (called by boto3.reosurce ('service name')). The resource API is more abstract than the client API and can be implemented without writing unnecessary information, so if you can do the same with each API, it is better to give priority to the resource API.

Overall article structure

First, let's reconfirm what Boto3, the client API, and the resource API were. After that, if you use both APIs, take up the usage patterns of SQS, S3, and DynamoDB one by one and compare them to see how they differ. Finally, I write a list and impressions of the services for which the resource API is currently provided.

What is Boto3

The AWS SDK provided with Python is used to connect from code to various AWS services (EC2, DynamoDB, S3, etc.). The API reference can be found in the following resources: Boto 3 Documentation

There are two main APIs: client API, which is a low-level API, and resource API, which is a high-level API. Specifically, it is called with the following description.

# Client API
boto3.client('sqs')

# Resource API
boto3.resource('sqs')

Next, let's check what characteristics each API has.

Client API (low level API)

This method has a one-to-one correspondence with the HTTP API provided by the AWS service. HTTP API It is fully mapped to, so you can do everything that the API can do. However, since it is a general-purpose setting, it is necessary to set the parameters to the API directly to the method. The following is an example of executing SQS send_message. QueueUrl etc. used in API are specified.

import boto3

#SQS client API version
sqs = boto3.client('sqs')

response = sqs.send_message(QueueUrl='https://sqs.us-east-2.amazonaws.com/123456789012/MyQueue', MessageBody='...')

Source: Boto3 Client API documentation (send_message) https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/sqs.html#SQS.Client.send_message

Resource API (high level API)

It is a high-level abstraction API compared to the client API. It is easier for developers to handle by inserting an abstract class in between instead of directly mapping with the API. Here, as an example, we will describe an example of sending_message with the resource API in the same way as the client API.

queueName='target-queue-name'

#SQS resource API version
sqs = boto3.resource('sqs')

response = sqs.get_queue_by_name
                QueueName = queueName
            ).send_message(
                MessageBody = '...'
            )

Reference source: "I tried using" Service Resource "in Boto3 (Python) (Lambda)" https://cloudpack.media/16114

Compared to the client API, you can write a message by querying the queue name without writing the SQS URL in the code. Developers only need to write the name of the queue because they don't have to be aware of the URL of the queue each time.

Comparison of client API and resource API (S3)

Next, compare the S3 client API and resource API. As an example, write the code to get the file name from the bucket.

#Common constant(Bucket and file prefixes in S3)
BUCKET_NAME= "xxx-bucket"
S3_PREFIX = "image-file-done/"
#S3 client API version
s3_client = boto3.client('s3')
#Return type:<class 'dict'>
s3_objects = s3_client.list_objects_v2(Bucket=BUCKET_NAME, Prefix=S3_PREFIX)

for filename in s3_objects['Contents']:
    print('client:'+filename['Key'])

#S3 resource API version
s3_resource = boto3.resource('s3')
#Return type:<class 'boto3.resources.collection.s3.Bucket.objectsCollection'>
s3_objects = s3_resource.Bucket(BUCKET_NAME).objects.filter(Prefix=S3_PREFIX)

for filename in s3_objects:
    print('resource:'+filename.key)

It's almost the same until the call, but the type after the call is different. When called by the client API, it is returned in dictionary type, so it is necessary to retrieve data that is conscious of the dictionary type format that is returned each time it is implemented. If it is a resource API, it is an object for boto3, so even if you use the resource API with other services, you can write code with a similar description.

Comparison of client API and resource API (DynamoDB)

Finally, compare the DynamoDB client API and resource API. Especially here, I don't understand the Boto3 document well, and it seems that I often copy it by mistake with reference to other descriptions. (It's my old self ...)

#Common constant(Table name, hash key name, sort key name)
TABLE_NAME='XXXXX_IFO'
HASH_KEY_NAME='XXXXX_CODE'
SORT_KEY_NAME='DATE_TIME'
#DynamoDB client version
dynamodb_client = boto3.client('dynamodb')
#Return type: <class 'dict'>
response = dynamodb_client.get_item(
    TableName=TABLE_NAME,
    Key={
        HASH_KEY_NAME:{
            'S': '54620100'  
        },
        SORT_KEY_NAME:{
            'S': '2019050621'
        }
    }
)
#DynamoDB resource API
dynamodb_resource = boto3.resource('dynamodb')
table = dynamodb_resource.Table(TABLE_NAME)
#Return type: <class 'dict'>
response = table.get_item(
    Key={
        HASH_KEY_NAME: '54620100',
        SORT_KEY_NAME: '2019050621'
    }
)

I wrote it in the client API after a long time, but it is a little difficult because I write the parameters in the same format as CLI. The return type itself is a dictionary type, but the operation inside the table can be done from the Table object, and the description of the Key item is considerably easier because you do not have to write the type information one by one.

Services for which resource API is provided (as of December 14, 2019)

The resource API offers a limited number of services. Specifically, the following services are supported.

Reference source: "Boto 3 Documentation" https://boto3.amazonaws.com/v1/documentation/api/latest/index.html

When using the above services, it seems necessary to first consider the resource API before using the client API. DynamoDB is a resource in Boto3's CodeExamples (sample documentation), but since other EC2 and CloudWatch are clients, it seems that you need to look at Available Services as well as CodeExamples.

Impressions

Until now, I used the client API and resource API without much consciousness, so I have summarized the results of various investigations as a reflection. As you can see from the SQS example, there is no need to write unnecessary information in the code part, so in the future I will first check if the service has a resource API, and if it is provided, think about whether it can be used well and then use the client API. I want to use it. It seems that there are many implementations written in the client API on Qiita and the net, so I would like to increase the information on the resource API by writing articles myself in the future.

Recommended Posts

Use Resource API rather than Client API in AWS SDK for Python (Boto3)
AWS SDK for Python (Boto3) development in Visual Studio 2017
Use AWS SDK for Python (boto) under Proxy environment
boto3 (AWS SDK for Python) Note
Use kintone API SDK for Python on Raspberry Pi (easily store data in kintone from Raspberry Pi)
Use pathlib in Maya (Python 2.7) for upcoming Python 3.7
[Cloudian # 1] Try to access object storage with AWS SDK for Python (boto3)
Use something other than a <br> string for the <br> dict key in Python
Tips for hitting the ATND API in Python
How to use Service Account OAuth and API with Google API Client for python
Don't use readlines () in your Python for statement!
Define boto3 Client API response in data class
Call Polly from the AWS SDK for Python
[BigQuery] How to use BigQuery API for Python -Table creation-
[For beginners] How to use say command in python!
[AWS IoT] Register things in AWS IoT using the AWS IoT Python SDK
Fleet provisioning with AWS IoT SDK for Python v2
Use config.ini in Python
Use dates in Python
Use Valgrind in Python
Use LiquidTap Python Client ③
Evernote API in Python
Use LiquidTap Python Client ②
Use profiler in Python
C API in Python 3
Use LiquidTap Python Client ①
Run AWS IoT Device SDK for Python on Raspberry Pi
Get data from analytics API with Google API Client for python
[AWS Lambda] Use any container Image in Python very simply
Hit Mastodon's API in Python
Let's use def in python
Use Trello API with python
Use let expression in Python
[Python] Scraping in AWS Lambda
AWS CDK-Lambda + API Gateway (Python)
Use Twitter API with Python
Use parameter store in Python
Search for strings in Python
Use MongoDB ODM in Python
Use list-keyed dict in Python
Techniques for sorting in Python
Use Random Forest in Python
Use regular expressions in Python
Use Spyder in Python IDE
Blender Python API in Houdini (Python 3)
Use subsonic API with python3
Simple IRC client in python
About "for _ in range ():" in python
Use e-Stat API from Python
Wrap (part of) the AtCoder Library in Cython for use in Python
Best practice for logging in JSON format on AWS Lambda / Python
[Introduction to Python] How to use the in operator in a for statement?
Install Networkx in Python 3.7 environment for use in malware data science books
A memo for those who use Python in Visual Studio (me)