Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AWS Ruby SDK CORE: Upload files to S3

I want to upload a file (any file, could be a .txt, .mp4, .mp3, .zip, .tar ...etc) to AWS S3 using AWS-SDK-CORE ruby SDK

Here is my code:

require 'aws-sdk-core'
Aws.config = {
  :access_key_id => MY_ACCESS_KEY
  :secret_access_key => MY_SECRET_KEY,
  :region => 'us-west-2'
}

s3 = Aws::S3.new
resp = s3.put_object(
  :bucket => "mybucket",
  :key => "myfolder/upload_me.sql",
  :body => "./upload_me.sql"
)

Now, Above code runs and creates a key myfolder/upload_me.sql which has only one line written and that is ./upload_me.sql which is wrong. The file upload_me.sql has several lines.

Expected behaviour is to upload the file upload_me.sql on S3 as mybucket/myfolder/upload_me.sql. But instead it just writes one line to mybucket/myfolder/upload_me.sql and that is ./upload_me.sql

Now, If I omit the :body part as below:

s3 = Aws::S3.new
resp = s3.put_object(
  :bucket => "mybucket",
  :key => "myfolder/upload_me.sql",
)

Then it just creates and empty key called mybucket/myfolder/upload_me.sql which is not even downloadable (well, even if it gets downloaded, it is useless)

Could you point me where I am going wrong?

Here is ruby-SDK-core documentation for put_object Method: http://docs.aws.amazon.com/sdkforruby/api/Aws/S3/V20060301.html#put_object-instance_method

UPDATE: If I try to upload the same file using AWS-CLI, it gets uploaded fine. Here is the command:

aws s3api put-object --bucket mybucket --key myfolder/upload_me.sql --body ./upload_me.sql
like image 614
slayedbylucifer Avatar asked Dec 26 '22 10:12

slayedbylucifer


2 Answers

So, After spending a frustrating sunday afternoon on htis issue, I finally cracked it. What I really needed is :body => IO.read("./upload_me.sql")

So my code looks like below:

s3 = Aws::S3.new
resp = s3.put_object(
  :bucket => "mybucket",
  :key => "myfolder/upload_me.sql",
  :body => IO.read("./upload_me.sql")
)
like image 166
slayedbylucifer Avatar answered Dec 27 '22 23:12

slayedbylucifer


The body variable is the contents that will be written to S3. So if you send a file to S3 you need to manually load by using File.read("upload_me.sql") something similar.

s3 = Aws::S3.new
resp = s3.put_object(
  :bucket => "mybucket",
  :key => "myfolder/upload_me.sql",
  :body => File.read("./upload_me.sql")
)

According to the documentation another way to do this is to use write on the bucket.

s3 = AWS::S3.new
key = File.basename(file_name)
s3.buckets["mybucket"].objects[key].write(:file => "upload_me.sql")
like image 45
Pafjo Avatar answered Dec 27 '22 23:12

Pafjo