Search code examples
pythonamazon-web-servicesamazon-s3boto3

Boto3 folder sync under new S3 'folder'


So, before anyone tells me about the flat structure of S3, I already know, but the fact is you can create 'folders' in S3. My objective with this Python code is to create a new folder named using the date of running and appending the user's input to this (which is the createS3Folder function) - I then want to sync a folder in a local directory to this folder.

The problem is that my upload_files function creates a new folder in S3 that exactly emulates the folder structure of my local set up.

Can anyone suggest how I would just sync the folder into the newly created one without changing names?

import sys
import boto3
import datetime
import os

teamName = raw_input("Please enter the name of your project: ")
bucketFolderName = ""

def createS3Folder():
    date = datetime.date.today().strftime("%Y") + "." + 
    datetime.date.today().strftime("%B") + "." + 
    datetime.date.today().strftime("%d")
    date1 = datetime.date.today()
    date = str(date1) + "/" #In order to generate a file, you must 
    put "/" at the end of key
    bucketFolderName = date + teamName + "/"  
    client = boto3.client('s3')
    client.put_object(Bucket='MY_BUCKET',Key=bucketFolderName)  
    upload_files('/Users/local/directory/to/sync')

def upload_files(path):
    session = boto3.Session()
    s3 = session.resource('s3')
    bucket = s3.Bucket('MY_BUCKET')
    for subdir, dirs, files in os.walk(path):
        for file in files:
            full_path = os.path.join(subdir, file)
            with open(full_path, 'rb') as data:
                bucket.put_object(Key=bucketFolderName, Body=data)

def main():
    createS3Folder()

if __name__ == "__main__":
    main()

Solution

  • Your upload_files() function is uploading to:

    bucket.put_object(Key=bucketFolderName, Body=data)
    

    This means that the filename ("Key") on S3 will be the name of the 'folder'. It should be:

     bucket.put_object(Key=bucketFolderName + '/' + file, Body=data)
    

    The Key is the full path of the destination object, including the filename (not just a 'directory').

    In fact, there is no need to create the 'folder' beforehand -- just upload to the desired Key.

    If you are feeling lazy, use the AWS Command-Line Interface (CLI) aws s3 sync command to do it for you!