Subscribe

Receive updates via email:

 Updates via RSS

Tag Cloud

Blog Archive

Thursday, December 11, 2008

Ruby: Amazon Associates Web Services (AWS / ECS) Sample Code

Step one is complete. In my last post, I discussed how I started working on the development of a Facebook Application using Ruby on Rails. While I mainly discussed the process of getting a Windows environment setup to develop and test Ruby, I also outlined the four step process that I was going through in order to build a relatively simple application.

To review, they were:

1. Acquire the data I was interested in.
2. Parse and save that data to a database (MySQL)
3. Display that data within an application. (Ruby on Rails)
4. Integrate that application with Facebook.

In this post, I will discuss the process I went through in the process – how to acquire the information that I was interested in. The focus here will be around creating a Ruby script – one that interacts with Amazon’s Associates Web Services (AWS / AAWS), formerly known as Amazon E-Commerce Services (ECS). The outcome I was looking for from this effort was to simply print the information from my script to the screen to validate I had the correct information. Storing that information in a database would be done in the next step.

My desire was to leverage some of the GEM packages that were already out there – and build my script on top of those components. It was an interesting process – to say the least. For that reason, I will be posting sample code – since I had such a hard time finding any as sample code snippets are important to relative newbies like myself that have not written code in years.

Let’s get started...

The main goal I was trying to accomplish in acquiring data was to lookup a specific item on Amazon and return key information about that item – primarily description, pricing, and other common elements of the product on Amazon. Simple enough, right?

That is what I thought. I started with some quick Google searches and immediate came across a gem called Amazon/ECS (link here) that I thought would do the trick. I downloaded that gem, amazon-ecs-0.5.3 and started trying to create a sample script. What I quickly discovered is that the sample script only facilitated a product search that returned a list of results, rather than the type of specifics that I was looking for. It took me some time to figure that out from looking at both the documentation and then the source code of the gem package.

While not well documented, the gem package seemed to do what it was supposed to do; it simply did not meet my requirements. It was time to see what alternatives were out there. And, unfortunately – this is where it gets confusing.

There are two gem packages out there for Amazon’s AWS and I’ll refer to them by the installation name since they are both call Amazon AWS – one is referred to in your script as ruby-aws (ruby-aws-1.2.0) (link here) and the other as amazon/aws (ruby-aaws-0.4.4) (link here). Given the information that I sorted through using Google – it took me way too long to figure this out. Hopefully you can learn from my experience here.

First, let’s start with ruby-aws – which I installed the package for using the command “gem install ruby-aws”. Very quickly, I realized that this package was similar to the amazon/ecs package and its main purpose was to search on Amazon and return results rather than returning information about a specific product. I knew I needed to move on, but as I referenced above – it took awhile to understand the differences between the two Amazon AWS gem packages for Ruby.

Once I finally found and installed the amazon/aws by entering “gem install ruby-aaws”, I looked for some sample code. As with most of these packages – the documentation and samples are not to the level of a beginner who is still learning a good amount of the concepts and syntax of the language. Still, in less than an hour I was able to make a request to the Amazon AWS web service via a Ruby script leveraging amazon/aws package. (You can get Ruby AAWS here)

Here were the results on my item search for a Playstation 3 80GB system, Amazon Item ID B001COU9I6 – slightly edited, for readability:

nil
upc = 711719801504
mpn = 711719801504
list_price =
formatted_price = $399.99
amount = 39999
currency_code = USD

ean
= 0711719801306
studio = Sony
binding = Video Game
publisher = Sony
is_memorabilia = 0
product_group = Video Games
hardware_platform =
Playstation 3
platform = PLAYSTATION 3
feature = Includes PlayStation 3
80 GB system, Dualshock 3 wireless controller, and free PlayStaion Network
membership, Internet ready, Wi-Fi, 80 GB of hard disk storage for all your
games, music, videos, and photos. Built-in Blu-ray player to give you the best
high-definition viewing experience and pristine picture quality. Play your
entire catalog of CDs and DVDs.
batteries_included = 0
operating_system
= PlayStation 3
edition = 80 GB
amazon_maximum_age = 240
title =
PlayStation 3 80GB
model = 711719801504
label = Sony
brand = Sony
release_date = 2008-08-20
item_dimensions = weight = 1500
width =
12.8
height = 3.9

product_type_name = VIDEO_GAME_HARDWARE
is_autographed = 0
package_quantity = 1
manufacturer = Sony
graphics_memory_size = 256
package_dimensions = weight = 1610
width
= 1380
length = 1730
height = 720

esrb_age_rating = Everyone
amazon_minimum_age = 60


And here is what you have been waiting for, the sample code that I used to generate the script. In order for you to run this code, all you need to do is copy it into a file called "amazon.rb" and execute it via command line by typing "ruby amazon.rb". Note: You must have an Amazon AWS API key (here) and replace it in the section below that says YOUR AMAZON API KEY HERE:

require 'amazon/aws'
require 'amazon/aws/search'

include Amazon::AWS
include Amazon::AWS::Search

ASSOCIATES_ID = "*YOUR ASSOCIATES ID HERE*"
KEY_ID = "*YOUR AMAZON AWS API KEY HERE*"

il = ItemLookup.new( 'ASIN', { 'ItemId' => 'B001COU9I6',
'MerchantId' => 'Amazon' })

rg = ResponseGroup.new( 'Medium' )

req = Request.new(KEY_ID, ASSOCIATES_ID)

resp = req.search( il, rg)
item_sets = resp.item_lookup_response[0].items
item_sets.each do |item_set|
item_set.item.each do |item|
attribs = item.item_attributes[0]
puts attribs
end
end

Let’s walk through the various components of the code to understand what is happening here…

First the setup. All we are doing here is setting up your script to have the right packages and classes available to Ruby when you execute.

#the gem packages your require
require 'amazon/aws'
require 'amazon/aws/search'

# your includes for this script
include Amazon::AWS
include Amazon::AWS::Search


Now we are building the request. The key components here are your Amazon AWS API key which is required (you can get one here), your Amazon Associates ID which is optional if you want to refer would-be buyers, and then the Amazon product ID and the store that it belongs to. There are several options you have here (see this page for more information) that can be customized to your needs – this accomplished exactly what I was trying to do. Note: If your item is sold by a third party and/or is out of stock for Amazon – then with the below settings you will not get a result without some tweaking.

Now we have the Response Group setting which controls the amount of information returned by your item lookup. So you can see the difference, for the Playstation 3 80GB system, here are the “Small”, “Medium”, and “Large” outputs. You can detect test this by simply changing the value of the response group in the below code to get the values you're looking for:

# Put your ASSOCIATES_ID and KEY_ID here, ASSOCIATES_ID is optional.
ASSOCIATES_ID = "*YOUR ASSOCIATES ID HERE*"
KEY_ID = "*YOUR AMAZON AWS API KEY HERE*"

# create your lookup object here using the ASIN or product ID
il = ItemLookup.new( 'ASIN', { 'ItemId' => 'B001COU9I6',
'MerchantId' => 'Amazon' })

# choose a response group of small, medium, and large which controls the number of attributes returned
rg = ResponseGroup.new( 'Medium' )

# add your associates id and api key to the request
req = Request.new(KEY_ID, ASSOCIATES_ID)


Now that we have built our request and know the expected output of our query, it is time to execute the query. In the section below, we are executing the item lookup with our parameters for the Item Lookup (il) and our Response Group (RG). While executing the query we return the set of attribute and then output them to the screen.

# execute the request and create a set for the item attributes
resp = req.search( il, rg)
item_sets = resp.item_lookup_response[0].items
item_sets.each do |item_set|
item_set.item.each do |item|
attribs = item.item_attributes[0]
# return the item attributes to the screen
puts attribs
end
end


And that’s it – with simple modifications to the above script (or none at all) you can lookup any item at Amazon.com with the Amazon AWS API in Ruby and return the attributes for further usage.

Hopefully this was simple for beginners (like me) and you now have some workable, usable sample code to get started with. If so, let me know with a comment.

Next up for me is now to store this data in a simple MySQL database!

11 comments:

Anonymous said...

Thanks for this guide. Found it very helpful.

Matt said...

Thanks for the post - very useful, was just going through this myself when I discovered your blog.
Cheers!

Matt said...

For more examples using this gem: http://github.com/res0nat0r/ruby-aws/tree/master/example

srboisvert said...

Has a bunch of code been mangled by your blogging software?

"attributes returned" is missing the # for a comment I think.

Your lines
item_sets.each do item_set
item_set.item.each do item
are missing the block bars around item_set and item.

and the file ends unexpectedly after puts attribs because the two do loops are unclosed

Other than those minor issues - thanks for this. Gives me enough info to get a start on using AAWS.

Ken Hanscom said...

Thanks for letting me know. Somehow it did get mangled and the software cut out the pipes and end statements. The partial comment line was my bad!

Good luck!
-Ken

OllieM said...

Great Post, but does anyone know how to parse and save the data in a MySQL database?

Ken Hanscom said...

Ollie,

Hopefully I'll finish up my post on this before the end of the weekend. :-)

-Ken

OllieM said...

Excellent, look forward to reading it!

Anonymous said...

HI Ken,

Have you any idea when you are going to be able to post the article about parsing the data to MySQL?

Ollie

Anonymous said...

Thanks, that was very helpful! Without your post I wouln't know where to get startet.
In my case I had to include the rubygems - otherwise I got a load error. If you have this problem, put this in the first line:

require 'rubygems'

Anonymous said...

Good guide. Did the MySQL sequel never materialize?