Every once in a while you run across a library that makes your day. Everything just works as you’d expect and you can focus on getting something done quickly. Today, for example, I needed to share a relatively large file with a significant number of people. Linking it up on our host just didn’t make sense. Added to which, just last week Marcel Molina Jr. had given a talk at The Rails Edge about his new AWS::S3 library. Coincidence? No, opportunity!

Getting started was so doggone easy that I just had to share…

1. Sign Up

Signing up is free, then you pay as you go. It’s currently $0.20 per gigabyte of data transferred and $0.15 per gigabyte stored each month.

Using your existing Amazon account, simply create an Amazon Web Services (AWS) account. Then just activate the S3 Web Service. You’ll receive an email that includes a link for fetching two keys: an access key id and a secret access key. You need these to make requests against the S3 service.

2. Download the AWS::S3 Library

gem install aws-s3

3. Play Around

Before you start shuttling bits around from inside an application, I recommend playing around with the API a bit. It’s fun, and made easier with an interactive shell called s3sh that comes with the AWS::S3 library. It’s your irb for Amazon S3.

s3sh

The first thing you’ll need to do is make a connection to your S3 account:

AWS::S3::Base.establish_connection!(
  :access_key_id     => 'your access key id goes here',
  :secret_access_key => 'your secret key goes here'
)

Then create a unique container, called a bucket, for your objects:

Bucket.create('intergalactic')

The bucket also serves as the global namespace for your objects. Here’s where the magic happens. Add an object to your bucket:

AWS::S3::S3Object.store('flight_manual.pdf', 
                        open('/path/to/local/flight_manual.pdf'), 
                        'intergalatic',
                        :access => :public_read)

Once the object has been stored in the big hard-drive in the sky, you can access it at http://s3.amazonaws.com/intergalactic/flight_manual.pdf.

That’s really all there is to it! It’s a convenient service fronted by an elegant Ruby library that adds up to a whole lot of fun and productivity. The API supports a boatload more options and operations, and it’s extremely well designed. Having polished off the task in a couple minutes, I found the short and sweet documentation to be just what I needed for diving deeper.

4. Integrate

For my one-off task today, using s3sh was super convenient. But at some point you’ll probably want to manage buckets and objects from within a larger program, such as a Rails application. That’s pretty easy given the AWS::S3 Ruby library. But just to get you started, I’ll leave you with this handy s3.rb file for storing an object in one fell swoop:

#!/usr/bin/env ruby
require 'rubygems'
require 'aws/s3'

AWS::S3::Base.establish_connection!(
  :access_key_id => ENV['AMAZON_ACCESS_KEY_ID'],
  :secret_access_key => ENV['AMAZON_SECRET_ACCESS_KEY']
)

file = ARGV.first
bucket = "intergalactic"

AWS::S3::S3Object.store(File.basename(file), 
                        open(file), 
                        bucket, 
                        :access => :public_read)

puts AWS::S3::S3Object.url_for(File.basename(file), bucket)[/[^?]+/]

To store the same object we did in the previous step, you’d type:

s3.rb /path/to/local/flight_manual.pdf

When all the bits have been safely tucked away, the public URL is printed. Share your objects at will, but remember that the meter’s running…