AWS provides SDKs for many popular technologies and programming languages. They make it easier for us to call AWS services from within our applications in that language or technology.
AWS SDK for Python is composed of two key Python packages: Botocore (the library providing the low-level functionality shared between the Python SDK and the AWS CLI) and Boto3 (the package implementing the Python SDK itself).
While using Python SDK, Client and Resource are two different abstractions within the boto3 SDK for making AWS service requests. When we want to make API calls to an AWS service with boto3, then we do so via a Client or a Resource.
We would typically choose to use either the Client abstraction or the Resource abstraction, but we can use both, as needed. Below is an outlined difference to help readers decide which/when to use.
Here's some more detailed information on what Client, Resource according to AWS Python SDK Boto3 Documentation.
Boto Client:
Clients provide a low-level interface to AWS whose methods map close to 1:1 with service APIs. All service operations are supported by clients. Clients are generated from a JSON service definition file.
In summary:
This is the original boto3 API abstraction
It provides low-level AWS service access
All AWS service operations are supported by clients
It exposes botocore client to the developer
It typically maps 1:1 with the AWS service API
It exposes snake-cased method names (e.g. ListBuckets API => list_buckets method)
Typically yields primitive, non-marshalled data (e.g. DynamoDB attributes are dicts representing primitive DynamoDB values)
Requires you to code result pagination
It is generated from an AWS service description
Here's an example of client-level access to an S3 bucket's objects:
import boto3
client = boto3.client('s3')
response = client.list_objects_v2(Bucket='mybucket')
for content in response['Contents']:
obj_dict = client.get_object(Bucket='mybucket', Key=content['Key'])
print(content['Key'], obj_dict['LastModified'])
Note: this client-level code is limited to listing at most 1000 objects. You would have to use a paginator, or implement your own loop, calling list_objects_v2() repeatedly with a continuation marker if there were more than 1000 objects.
Boto Resource:
Resources represent an object-oriented interface to Amazon Web Services (AWS). They provide a higher-level abstraction than the raw, low-level calls made by service clients. To use resources, you invoke the resource() method of a Session and pass in a service name:
In summary:
This is the newer boto3 API abstraction
It provides a high-level, object-oriented API
It does not provide 100% API coverage of AWS services
It uses identifiers and attributes
It has actions (operations on resources)
It exposes sub-resources and collections of AWS resources
Typically yields marshaled data, not primitive AWS data (e.g. DynamoDB attributes are native Python values representing primitive DynamoDB values)
Does result pagination for you
It is generated from an AWS resource description
Here's the equivalent example using resource-level access to an S3 bucket's objects:
import boto3
s3 = boto3.resource('s3')
bucket = s3.Bucket('mybucket')
for obj in bucket.objects.all():
print(obj.key, obj.last_modified)
Note: in this case you do not have to make a second API call to get the objects; they're available to you as a collection on the bucket. These collections of sub-resources are lazily-loaded.
You can see that the Resource version of the code is much simpler, more compact, and has more capability (for example it does pagination for you and it exposes properties instead of a raw dictionary). The Client version of the code would actually be more complicated than shown above if you wanted to include pagination.