Uploading Files to S3 using AWS SDK Ruby Gem

To upload files to your Amazon S3 bucket, you can use the aws-sdk version 2. By default the gem looks for the credentials in the environment variables. So you must export the values in a terminal like this:

export AWS_ACCESS_KEY_ID='my-very-secret-key'

You can verify it is set by doing:

echo $AWS_ACCESS_KEY_ID

You must set AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY and AWS_REGION. You can create a S3 resource for the region where your bucket exists and create an object with a unique file name and call upload_file as shown below.

require 'aws-sdk'

file_name = 'your-file.mp4'

s3 = Aws::S3::Resource.new(region: ENV['AWS_REGION'])
obj = s3.bucket('your-s3-bucket-name').object(file_name)
puts "Uploading file #{file_name}"
obj.upload_file("/Users/username/path/to/#{file_name}")
puts "Done"

We can add a spinner to make it clear that progress is being made. The modified version is shown below:

require 'aws-sdk'

def with_spinner
  chars = %w[| / - \\]
  not_done = true
  spinner = Thread.new do
    while not_done do  
      print chars.rotate!.first
      sleep 0.1
      print "\b"
    end
  end
  yield.tap do         # After yielding to the block, save the return value
    not_done = false   # Tell the thread to exit, cleaning up after itself…
    spinner.join       # …and wait for it to do so.
  end                  # Use the block's return value as the method's
end

# By default aws-sdk looks at these environment variables
# ENV['AWS_REGION'], ENV['AWS_ACCESS_KEY_ID'] and ENV['AWS_SECRET_ACCESS_KEY'] 

def actual_job
  ENV['AWS_REGION'] = 'us-east-1'
  file_name = 'test.mp4'

  s3 = Aws::S3::Resource.new(region: ENV['AWS_REGION'])
  obj = s3.bucket('s3-bucket-name').object(file_name)
  print "Uploading file #{file_name}"

  obj.upload_file("/Users/bugs/Desktop/#{file_name}")
end

with_spinner do 
  actual_job
end

puts "Done!"

To retrieve the size of the file, I used to use the curl command, you can execute any command in ruby using the Kernel tick method.

command = `curl -I -s https://your-s3-bucket-url/test.mp4 | grep 'Content-Length'`
puts command

Instead of using curl, to be consistent, we can use aws-sdk library to find the file size:

require 'aws-sdk'

o = Aws::S3::Object.new('your-s3-bucket', 'your-s3-file-name-with-extension')
puts o.content_length

This automates some of the steps of screencast workflow for rubyplus.com. Since I no longer have to login to a password manager, login to aws console, use their UI to go to the correct bucket and upload the file manually.


Related Articles


Ace the Technical Interview

  • Easily find the gaps in your knowledge
  • Get customized lessons based on where you are
  • Take consistent action everyday
  • Builtin accountability to keep you on track
  • You will solve bigger problems over time
  • Get the job of your dreams

Take the 30 Day Coding Skills Challenge

Gain confidence to attend the interview

No spam ever. Unsubscribe anytime.