Tuesday, August 19, 2008

Reading from Freebase using C#

Update : Seems Freebase no longer requires the cookie authentication - comment out that line and it works fine. Cool.

Freebase is one of my favourite things EVER on the web.

I'm working on a project just now and need to read from FreeBase. Alas I couldn't find any C# examples (if you know of any please let me know). As FreeBase is in early stages it required Cookie authentication - they say they will open up in the future.

Anyway, here is the code that does the same thing as the Perl, PHP and JavaScript code on this Freebase page. Enjoy :)


using System;
using System.IO;
using System.Net;
using System.Text;
using System.Security.Authentication;

namespace FreebaseSample
{
public class FreeFind
{
private static string server = "http://www.freebase.com";
private static string queryurl = "/api/service/mqlread";
private static string path = "/api/account/login";
private static string username = "";
private static string password = "";
private static CookieContainer authCookies = null;



public void Ask(string band)
{
// This is our MQL query
// Find a band
// With the specified name
// We want to know about albums
// Return album names
// And release dates
// Order by release date
string query = "{\"type\": \"/music/artist\",\"name\": \"" + band + "\",\"album\": [{\"name\":null,\"sort\": \"release_date\", \"release_date\":null}]}";

string envelope = "{\"a0\":{\"query\":"+query+"}}";
string url = server + queryurl + "?queries=" + System.Web.HttpUtility.UrlDecode(envelope);

HttpWebRequest request = (HttpWebRequest)System.Net.WebRequest.Create(url);
request.Method = "GET";
request.ContentType = "application/x-www-form-urlencoded";
request.CookieContainer = authCookies;

HttpWebResponse response = (HttpWebResponse)request.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream());

Console.WriteLine(reader.ReadToEnd());
reader.Close();
response.Close();
}

/// <summary>
/// Authentication.
/// </summary>
public void Authenticate()
{
string authURI = server + path;

// Create the web request body:

string body = string.Format("username={0}&password={1}", username, password);
byte[] bytes = Encoding.UTF8.GetBytes( body );

// Create the web request:

HttpWebRequest request = (HttpWebRequest)System.Net.WebRequest.Create( authURI );
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.CookieContainer = new CookieContainer();
request.ContentLength = bytes.Length;

// Create the web request content stream:
using ( Stream stream = request.GetRequestStream() )
{
stream.Write( bytes, 0, bytes.Length );
stream.Close();
}

// Get the response & store the authentication cookies:

HttpWebResponse response = (HttpWebResponse)request.GetResponse();

if ( response.Cookies.Count < 2 )
throw new AuthenticationException( "Login failed. Is the login / password correct?" );

authCookies = new CookieContainer();
foreach ( Cookie myCookie in response.Cookies )
{
authCookies.Add(myCookie);
}

response.Close();
}
}
}






You can call it as so ...


using System;

namespace FreebaseSample
{
class Program
{

static void Main(string[] args)
{
FreeFind f = new FreeFind();
f.Authenticate();
f.Ask("U2");
Console.ReadKey();
}


}
}

You get something like the following JSON response ...



{
"status": "200 OK",
"a0": {
"code": "/api/status/ok",
"result": {
"album": [
"Three",
"Another Day",
"11 O'Clock Tick Tock",
"A Day Without Me",
.
.
.
"U2 Popmart - Miss Sarajevo (disc 2)",
"Unplugged",
"Zoo TV Tour (disc 2: Live Transmission)",
"Shaped",
"The Complete U2",
"Wide Awake in America"
],
"type": "/music/artist",
"name": "U2"
}
},
"code": "/api/status/ok"
}

1 comment:

Cuong said...

Thanks livz,
I'm reading freebase, I hope u continue post here