Categories
AWS

How to Access Object Storage Using the S3 API in Python?

Home » AWS » How to Access Object Storage Using the S3 API in Python?

In our last post, we discussed how to bulk rename files in AWS S3 using Python. Today, let’s talk about how to access object storage using the S3 API in Python. To access object storage using the S3 API in Python, the demo code is as follows.

How to use boto3 to connect to S3?

 

#!/usr/bin/python3
import os
import time
import boto
import boto.s3.connection
import argparse
import sys
# You need to modify the secret_access_key and access_key_id for the corresponding user.
access_key = "ZQAC7EA0G95ZBUAQXDQP"
secret_key = "pfgP1XiMXxJMoJ8pQv46VmndkBMTLwz2TDt0Ogl5"
HOST = "127.0.0.1"
PORT = 7480
useage = """usage: s3client.py [-h] [-c host] [-p port] [--bucket bucket_name]
                   [--create_bucket bucket_name] [--delete_bucket bucket_name]
                   [--list_buckets] [--create_object object]
                   [--delete_object object] [--list_objects]
optional arguments:
  -h, --help           
                show this help message and exit
  -c host, --client host
                The client to connect host. e.g. -c 172.30.28.181
  -p port, --port port      
                The port of server to be connected. e.g. -p 7480
  --bucket bucket_name       
                Specify a bucket. e.g. --bucket my-bucket
  --create_bucket bucket_name
                Creates a new S3 bucket. e.g. --create_bucket my-bucket
  --delete_bucket bucket_name    
                Deletes a new S3 bucket. e.g. --delete_bucket my-bucket
  --list_buckets           
                List all buckets. e.g. --list_buckets
  --create_object       
                Adds an object to a bucket. e.g. --bucket my-bucket --create_object --key file.txt --body /root/file.txt
  --key       
                Specified object key. e.g. --bucket my-bucket --create_object --key file.txt --body /root/file.txt
  --body       
                Specified object body. e.g. --bucket my-bucket --create_object --key file.txt --body /root/file.txt
                
  --get_object 
                Gets an object from a bucket. e.g. --bucket my-bucket --get_object --key file.txt --body /root/file.txt
  --copy_object 
                Copy a new S3 bucket. e.g. --copy_object my-bucket/testfile --key testfile --bucket your-bucket
                
  --delete_object 
                Removes an object from a bucket. e.g. --bucket my-bucket --delete_object --key file.txt
                
  --list_objects           
                List all objects in a bucket. e.g. --bucket my-bucket --list_objects"""
                    
parse = argparse.ArgumentParser(add_help=False)
parse.add_argument(
    "-h",
    "--help",
    action='store_true',
)
parse.add_argument(
    "-c",
    "--client",
    metavar="host",
)
parse.add_argument(
    "-p",
    "--port",
    metavar="port",
)
parse.add_argument(
    "--bucket",
    metavar="bucket_name",
)
parse.add_argument(
    "--create_bucket",
    metavar="bucket_name",
)
parse.add_argument(
    "--delete_bucket",
    metavar="bucket_name",
)
parse.add_argument(
    "--list_buckets",
    action='store_true',
)
parse.add_argument(
    "--create_object",
    action='store_true',
)
parse.add_argument(
    "--key",
    metavar="key",
)
parse.add_argument(
    "--body",
    metavar="file",
)
parse.add_argument(
    "--copy_object",
    metavar="object",
)
parse.add_argument(
    "--get_object",
    action='store_true',
)
parse.add_argument(
    "--delete_object",
    action='store_true',
)
parse.add_argument(
    "--list_objects",
    action='store_true',
)
args = parse.parse_args()
class S3client:
    def __init__(self, host, port) -> None:
        self.conn = boto.connect_s3(
                aws_access_key_id = access_key,
                aws_secret_access_key = secret_key,
                host = host,
                port = port,
                debug=0,
                is_secure=False,               # uncomment if you are not using ssl
                calling_format = boto.s3.connection.OrdinaryCallingFormat(),
                )
        self.bucket = None
    
    def __del__(self):
        self.conn.close()
        
    def get_bucket(self, bucket_name):
        for i in self.conn.get_all_buckets():
            if i.name == bucket_name:
                self.bucket = i
                break 
    @property
    def create_bucket(self):
        self.conn.create_bucket(args.create_bucket)
        print("Bucket %s created" % args.create_bucket)
    
    @property
    def delete_bucket(self):
        self.conn.delete_bucket(args.delete_bucket)
        print("Bucket %s removed" % args.delete_bucket) 
        
    @property       
    def list_buckets(self):
        for i in self.conn.get_all_buckets():
            print(i.name)
      
    @property     
    def create_object(self):
        self.get_bucket(args.bucket)
        start_time = time.time()
        key = self.bucket.new_key(args.key)
        key.set_contents_from_filename(os.path.basename(args.body))
        print("upload: '%s' -> 's3://%s/%s' [1 of 1]" % (args.body, args.bucket, args.key))
        print("Time: %.2fs " % float(time.time()-start_time))
    
    @property 
    def get_object(self):
        self.get_bucket(args.bucket)
        key = self.bucket.get_key(args.key)
        key.get_contents_to_filename(args.body)
        print("download: 's3://%s/%s' to %s " % (args.bucket, args.key, args.body))
    
    @property 
    def copy_object(self):
        self.conn.get_bucket(args.bucket).copy_key(new_key_name=args.key, 
                            src_bucket_name=args.copy_object.split("/")[0],
                            src_key_name='/'.join(args.copy_object.split("/")[1:]))
        
        print("copy: 's3://%s' to 's3://%s/%s' " % (args.copy_object, args.bucket, args.key))
        
    @property     
    def list_objects(self):
        self.get_bucket(args.bucket)
        for key in self.bucket.list():
            print("%s\t%-10s\t%s" % (key.last_modified, key.size, key.name))
    
    @property 
    def delete_object(self):
        self.get_bucket(args.bucket)
        self.bucket.delete_key(args.key)
        print("delete: 's3://%s/%s'" % (args.bucket, args.key))
if __name__ == "__main__":
    if args.help:
        print(useage)
        sys.exit(0)
    host = HOST if not args.client else args.client
    port = PORT if not args.port else args.port
    s3 = S3client(host, port)
    try:
        for i in args._get_kwargs():
            if getattr(args, i[0]):
                hasattr(s3, i[0])
    except Exception as e:
        print("no valid command found; please check!")
        print(useage)

How to use boto3 to connect to S3?

 

#!/usr/bin/python3
import json
import os
import time
import datetime
import argparse
import sys
import boto3
# You need to modify the secret_access_key and access_key_id for the corresponding user.
access_key = "0INSHOH6YXYN9ZW9P2VT"
secret_key = "ZZzQ2CvfmtI2Wn5UE11WvlQtBX92pIIpSfyhRalv"
# Modify the following parameters based on your actual environment:
http_protocol = "https"         
ca = "/tmp/civetweb.pem"
HOST = "vip"              # IP or domain name, 127.0.0.1/vip
PORT = 8090
useage = """usage: s3client.py [-h] [-c host] [-p port] [--bucket bucket_name]
                   [--create_bucket bucket_name] [--delete_bucket bucket_name]
                   [--list_buckets] [--put_object object] [--copy_object object]
                   [--delete_object object] [--list_objects] [--ca cert.pem]
                   [--http_protocol https]
optional arguments:
  -h, --help           
                show this help message and exit
  -c host, --client host
                The client to connect host. e.g. -c 172.30.28.181
  -p port, --port port      
                The port of server to be connected. e.g. -p 7480
  --http_protocol https
                Specify http protocol, usually used with --ca. e.g. --http_protocol https
  --ca  cert.pem      
                A filename of the CA cert bundle to uses. e.g. --ca /etc/ceph/ca/civetweb.pem
                
  --bucket bucket_name       
                Specify a bucket. e.g. --bucket my-bucket
  --create_bucket bucket_name
                Creates a new S3 bucket. e.g. --create_bucket my-bucket
  --delete_bucket bucket_name    
                Deletes a new S3 bucket. e.g. --delete_bucket my-bucket
  --list_buckets           
                List all buckets. e.g. --list_buckets
  --put_object       
                Adds an object to a bucket. e.g. --bucket my-bucket --put_object --key file.txt --body /root/file.txt
  --key       
                Specified object key. e.g. --bucket my-bucket --put_object --key file.txt --body /root/file.txt
  --body       
                Specified object body. e.g. --bucket my-bucket --put_object --key file.txt --body /root/file.txt
                
  --get_object 
                Gets an object from a bucket. e.g. --bucket my-bucket --get_object --key file.txt --body /root/file.txt
  --copy_object 
                Copy a new S3 bucket. e.g. --copy_object my-bucket/testfile --key testfile --bucket your-bucket
                
  --delete_object 
                Removes an object from a bucket. e.g. --bucket my-bucket --delete_object --key file.txt
                
  --list_objects           
                List all objects in a bucket. e.g. --bucket my-bucket --list_objects
                
Example:
1. Use HTTP protocol to get the bucket.
  python3 s3client.py --list_buckets --http_protocol http
2. Use HTTPS protocol to get the bucket. 
  python3 s3client.py --list_buckets --http_protocol https --ca /etc/ceph/ca/civetweb.pem
3. Use HTTP protocol to get objects.
  python3 s3demo.py --list_objects --bucket python -c 172.30.25.99 -p 7480 --http_protocol http  
4. Use HTTPS protocol to get objects.
  python3 s3demo.py --list_objects --bucket python -c vip -p 8090 --http_protocol https        
"""
                    
parse = argparse.ArgumentParser(add_help=False)
parse.add_argument(
    "-h",
    "--help",
    action='store_true',
)
parse.add_argument(
    "-c",
    "--client",
    metavar="host",
)
parse.add_argument(
    "-p",
    "--port",
    metavar="port",
)
parse.add_argument(
    "--http_protocol",
    metavar="https",
)
parse.add_argument(
    "--ca",
    metavar="cert.pem",
)
parse.add_argument(
    "--bucket",
    metavar="bucket_name",
)
parse.add_argument(
    "--create_bucket",
    metavar="bucket_name",
)
parse.add_argument(
    "--delete_bucket",
    metavar="bucket_name",
)
parse.add_argument(
    "--list_buckets",
    action='store_true',
)
parse.add_argument(
    "--put_object",
    action='store_true',
)
parse.add_argument(
    "--key",
    metavar="key",
)
parse.add_argument(
    "--body",
    metavar="file",
)
parse.add_argument(
    "--copy_object",
    metavar="object",
)
parse.add_argument(
    "--get_object",
    action='store_true',
)
parse.add_argument(
    "--delete_object",
    action='store_true',
)
parse.add_argument(
    "--list_objects",
    action='store_true',
)
args = parse.parse_args()
class S3client:
    def __init__(self, host, port) -> None:
        
        self.client = boto3.client(
                service_name='s3',
                aws_access_key_id = access_key,
                aws_secret_access_key = secret_key,
                endpoint_url=f'{http}://{host}:{port}',
                verify=ca
                )
    @property
    def create_bucket(self):
        response = self.client.create_bucket(Bucket=args.create_bucket)
        self.print_json(response)
    
    @property
    def delete_bucket(self):
        response = self.client.delete_bucket(Bucket=args.delete_bucket)
        self.print_json(response)
        
    @property       
    def list_buckets(self):
        response = self.client.list_buckets()
        self.print_json(response)
            
    @property     
    def put_object(self):
        try:
            start_time = time.time()
            body = os.path.abspath(args.body) if args.body else None
            response = self.client.put_object(Body=body, Bucket=args.bucket, Key=args.key)
            print("upload: '%s' -> 's3://%s/%s' [1 of 1]" % (args.body, args.bucket, args.key))
            print("Time: %.2fs " % float(time.time()-start_time))
            self.print_json(response)
        except Exception as e:
            print(e)
    
    @property 
    def get_object(self):
        try:
            self.client.download_file(Bucket=args.bucket,
                        Key=args.key,
                        Filename=args.body)
            print("download: 's3://%s/%s' to %s " % (args.bucket, args.key, args.body))
        except Exception as e:
            print(e)
    
    @property 
    def copy_object(self):
        response = self.client.copy_object(
                    Bucket=args.bucket,
                    CopySource=args.copy_object,
                    Key=args.key,
                )
        print("copy: 's3://%s' to 's3://%s/%s' " % (args.copy_object, args.bucket, args.key))
        self.print_json(response)
        
    @property     
    def list_objects(self):
        response = self.client.list_objects(
            Bucket=args.bucket,
            )
        self.print_json(response)
    @property 
    def delete_object(self):
        try:
            response = self.client.delete_object(
                    Bucket=args.bucket,
                    Key=args.key,
                    )
            print("delete: 's3://%s/%s'" % (args.bucket, args.key))
            self.print_json(response)
        except Exception as e:
            print(e)
            
    @staticmethod
    def print_json(data):
        print(json.dumps(data,cls=DateEncoder, sort_keys=True, indent=4, separators=(', ', ': '), ensure_ascii=False))
class DateEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, datetime.datetime):
            return obj.strftime("%Y-%m-%d %H:%M:%S")
        else:
            return json.JSONEncoder.default(self,obj)
if __name__ == "__main__":
    if args.help:
        print(useage)
        sys.exit(0)
    host = HOST if not args.client else args.client
    port = PORT if not args.port else args.port
    http = http_protocol if not args.http_protocol else args.http_protocol
    if http_protocol == "https":
        if args.ca:
            ca = args.ca
        else:
            ca = ca
    else:
        ca = False
    s3 = S3client(host, port)
    try:
        for i in args._get_kwargs():
            if getattr(args, i[0]):
                hasattr(s3, i[0])
    except Exception as e:
        print("no valid command found; please check!\nUsage: python3 s3demo.py -h")

 

By Jaxon Tisdale

I am Jaxon Tisdale. I will share you with my experience in Network, AWS, and databases.

Leave a Reply

Your email address will not be published. Required fields are marked *