Skip to content

Instantly share code, notes, and snippets.

@danishabdullah
Last active February 10, 2016 13:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save danishabdullah/f6b7f27188262e10c9d1 to your computer and use it in GitHub Desktop.
Save danishabdullah/f6b7f27188262e10c9d1 to your computer and use it in GitHub Desktop.
Boto3 S3 helper

Following example class shows how to use boto3 to upload files to s3 using a programmable configuration

from uuid import uuid1

import boto3
from botocore.client import Config
from boto3.session import Session

class S3Storage(object):
    def __init__(self,
                 s3_host=AWS_S3_HOST,
                 s3_bucket=AWS_S3_BUCKET,
                 aws_access_key_id=AWS_ACCESS_KEY_ID,
                 aws_secret_access_key=AWS_SECRET_ACCESS_KEY,
                 aws_region=AWS_REGION):
        self.host = s3_host
        self.bucket_name = s3_bucket
        self.aws_access_key_id = aws_access_key_id
        self.aws_secret_access_key = aws_secret_access_key
        self.aws_region = aws_region
        self._s3_resource = None
        self._s3_client = None

    @property
    def s3_resource(self):
        """
        Provide v4 Session for S3
        """
        self._s3_resource = self._s3_resource or Session(aws_access_key_id=self.aws_access_key_id,
                                                         aws_secret_access_key=self.aws_secret_access_key,
                                                         region_name=self.region).resource('s3', config=Config(
            signature_version='s3v4'))
        return self._s3_resource

    @property
    def s3_client(self):
        """
        Provides access to v4 Client for s3
        """
        self._s3_client = self._s3_client or boto3.client('s3',
                                                          config=Config(signature_version='s3v4'))
        return self._s3_client

    @property
    def bucket(self):
        """
        Provides access to the s3 Bucket object
        """
        return self.s3_resource.Bucket(self.bucket_name)

    def write(self, df, filename):
        """
        Uploads a pandas dataframe as a csv file to S3. Overrides existing. Makes the file public. Returns link to the file.
        """
        bucket = self.bucket
        tmpfile = "/tmp/{}.tmp".format(uuid1().hex)
        df.to_csv(tmpfile, encoding='utf-8', index=False)
        obj = bucket.Object(filename)
        obj.upload_file(tmpfile)
        acl = self.s3_resource.ObjectAcl(self.bucket_name, filename)
        acl.load()
        acl.put(ACL='public-read')
        return self.get_link(feedtype)

    def get_link(self, filename):
        """
        Returns presigned url for the file in the bucket.
        """
        return self.s3_client.generate_presigned_url(
            ClientMethod='get_object',
            Params={
                'Bucket': self.bucket_name,
                'Key': filename
            }
        )
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment