Freebase => Ruby using the JSON library

August 24, 2007

I’ve been playing with Locomotive and Ruby on Rails. Two things I really like about this: (as everyone says) you can generate something in a few minutes …and you can test it in your browser offline (aka on Caltrain).

I was able to pull down Freebase data (influences) into Ruby using this example on the Yahoo’s Developer site which makes use of the JSON library for Ruby to pull Yahoo search results into Ruby. The only real change is the base_url and query. For more on the Metaweb read query language, check their excellent documentation. Here’s my Freebase controller, which formulates a query based on a name, gets a JSON response from Freebase, converts it to a hash and sends that hash to a view:

class FreebaseController < ApplicationControllerrequire 'rubygems'
require 'json'
require 'net/http'
def metaweb_read(name)
base_url = "http://www.freebase.com/api/service/mqlread"
envelope = '?queries={"qname":{"query":{"id":null,"influenced":[{"id":null,"name":null,"type":"/people/person"}],"influenced_by":[{"id":null,"name":null,"type":"/people/person"}],"name":"' + name + '","type":"/user/mikelove/default_domain/influence_node"}}}'
url = "#{base_url}#{URI.encode(envelope)}"
resp = Net::HTTP.get_response(URI.parse(url))
data = resp.body
# we convert the returned JSON data to native Ruby
# data structure - a hash
result = JSON.parse(data)
# if the code key indicates an error, we raise an error
if result['code'] == '/api/status/error'
raise "web service error #{url}"
end
return result
end
def freebase_test
@influences = metaweb_read('Samuel Taylor Coleridge')
end
end

The envelope variable is where you drop the query plus an envelope. It is two strings with the name of a historic figure injected in the middle. I use single quotes around the two strings because the metaweb query language uses double quotes on everything. Here it is broken up:

'?queries={"qname":{"query":{
"id":null,
"influenced":[{
"id":null,"name":null,"type":"/people/person"
}],
"influenced_by":[{
"id":null,"name":null,"type":"/people/person"
}],
"name":"'
+ name + '",
"type":"/user/mikelove/default_domain/influence_node"
}}}'

Then I can use the @influences hash in a view (freebase_test.rhtml):
<p><%= @influences['qname']['result']['name'] %> influenced:</p>
<% for person in @influences['qname']['result']['influenced'] %>
<p><%= person['name'] %></p>
<% end %>

Which prints out:

Samuel Taylor Coleridge influenced:

Ralph Waldo Emerson

Mary Shelley

Leave a Reply