Search code examples
amazon-web-servicespython-2.7amazon-s3boto3

Uploading a folder full of files to a specific folder in Amazon S3


There have been a few other questions like this, but none seem to have answered my problem specifically. I have a folder full of files I want to upload to Amazon S3, and I have tried various different things, all leading to no upload. Here's the code I have now. It successfully creates the folder on S3, but doesn't upload.

import os
import boto3

s3_bucket = 'bucketname'
s3_bucket_region = 'us-east-1'
folder = 'FolderName'

key_name = folder + '/' 
s3_connect = boto3.client('s3', s3_bucket_region)
try:
    bucket = s3_connect.put_object(Bucket=s3_bucket, Key=key_name)
    print "Bucket:", bucket
except Exception as e:
    print "Bucket Error " , e

# upload File to S3
for filename in os.listdir(folder):

    file_key_name = folder + '/' + filename
    local_path = os.getcwd()
    local_name = local_path + '/' + key_name + filename
    upload = s3_connect.upload_file(local_name, s3_bucket, file_key_name)

I have tried a file_key_name of just something like 'FolderName/' as well as 'FolderName/FileName'. I thought at first the first argument (local_name) didn't need a full path, but a relative path would work, but neither a full or relative path works.

What am I missing? The docs are pretty woefully lacking in this department. Plus it doesn't throw an error, it just doesn't upload.


Solution

  • Your code works perfectly fine for me, but you need to remove the try/catch section that creates the folder on Amazon S3.

    Amazon S3 does not actually support folders. Rather, the Key of an object includes the full path (eg images/foo.jpg). Therefore, you don't need to create the folders before storing a file in them (since they do not exist!).

    Your code will have difficulty with nested folders. You might consider using the aws s3 sync or aws s3 cp commands in the AWS Command-Line Interface (CLI) if you don't need it written in your own code.