Sidebar:
Last.fm in Silverlight
For Silverlight developers, working with the Last.fm API is mostly a matter of using WebClient to send requests to the Last.fm server and using LINQ to query the XML document that comes back in response.
We'll use a little example application to walk through this approach. The example Silverlight application shows two list boxes, one for Artists, and one for Events. Both lists start out empty. When you click the "Get Artists" button, the application calls the Last.fm API to fetch the top artists for a given
(hard coded) user. Then, when you click on an entry in the Artists list, the application calls Last.fm to get any events associated with that artist, and displays them in the results list. The screenshot below shows the example with both lists populated.
A Silverlight example application that uses two Last.fm calls to retrieve artists and events.
When the button is clicked, we build the request URL and hand it off to WebClient:
private void
FetchButton_Click(object sender, RoutedEventArgs e)
{
ArtistsList.Items.Clear();
EventsList.Items.Clear();
string getTopArtists = "http://ws.audioscrobbler.com/2.0/method=user.gettopartists&user=xxx&api_key=xxx";
WebClient client = new
WebClient();
client.DownloadStringCompleted
+= new DownloadStringCompletedEventHandler(getTopArtists_DownloadStringCompleted);
client.DownloadStringAsync(new Uri(getTopArtists));
}
We set up a
download complete event handler, then call the download method. WebClient
retrieves the response document asynchronously, then calls our handler. In the
handler, we use LINQ to write queries against the parsed XML document:
XDocument doc = XDocument.Parse(e.Result);
//get the list of
artist names.
var artists = from results in doc.Descendants("artist")
select results.Element("name").Value.ToString();
foreach (string
artist in artists)
{
ArtistsList.Items.Add(artist);
}
The code above walks through each "artist" element in the returned XML and extracts the text from the "name" sub-element. Then we add each artist name to the listbox.
When the user clicks an artist name, we use the same WebClient and LINQ combination to get the events for the selected artist. This time, we build an artist.getEvents Last.fm API call from the selected artist name like this:
string artist =
ArtistsList.SelectedItem.ToString();
string getEvents = string.Format(
"http://ws.audioscrobbler.com/2.0/?method=artist.getevents&artist={0}&api_key=xxx", artist);
When that call returns, we again use LINQ to extract the event information we're looking for and populate the events list box.
var evts = from
results in doc.Descendants("event")
select new
{
title = results.Element("title").Value.ToString(),
venueName = results.Element("venue").Element("name").Value.ToString(),
startDate = results.Element("startDate").Value.ToString()
};
EventsList.Items.Clear();
foreach (var evt in evts)
{
EventsList.Items.Add(evt.title + " at "
+ evt.venueName + " on " +
evt.startDate);
}
As these examples show, WebClient and LINQ make it relatively easy to consume REST-style
web services, such as Last.fm, in Silverlight. And because WebClient works asynchronously, you can fetch data from Last.fm without interfering with the main UI.
Last.fm is Internet radio tuned to the taste of each listener, guided by personal listening history and by the collective selections of the crowd. Last.fm is also a social networking site that maps the connections between artists, tracks, and users. Exploring those connections on the
http://Last.fm is a great way to discover new music and new artists (wandering freely around those connections is a great way to fritter away an afternoon). Sounds great, you say. But wouldn't this all be more fun if I could do it in code?
Turns out, you can. The http://www.last.fm/api is a collection of HTTP web services that give developers access to the wealth of music and listening data amassed by the site, including artist, album, and track information, popularity rankings, tags, and similarity recommendations. You can also write user-related data (such as user tags for a track) through the API, making it possible to build limited Last.fm clients. Finally, the API supports submitting user listening information to Last.fm for recording in user listening history (what Last.fm calls "scrobbling"). The one thing you can't currently do through the API is stream music, meaning you can't write a Last.fm player application using the
web service.
To use the Last.fm API you need an API key, and (for some calls) a shared secret, both of which you can get from Last.fm through a free API account.
Calling Last.fm
Last.fm provides two API flavors, a REST-style interface that uses HTTP GET and POST and returns XML, and an XML-RPC interface. The two APIs are similar, except for the actual request and response formats. I'll focus on the REST-style interface in this article.
Because the Last.fm API is served up through HTTP, you can work with it from any platform with access to web services, including web applications, desktop applications, and mobile devices. Depending on the type of application you are building, there are a number of techniques for working with REST web services using .NET 3.5. The details are outside the scope of this article, but the links below are good resources (also see the sidebar, "Last.fm in Silverlight," for an example of working with the API from a Silverlight client).
Except for the scrobbler API, all of the Last.fm web service calls are made to URLs based at http://ws.audioscrobbler.com/2.0/. For write calls, method and parameters are POSTed to this URL. For read calls, the query string specifies the method and any parameters, for example:
http://ws.audioscrobbler.com/2.0/?method=tag.getTopTags&api_key=xxx
This URL specifies the tag.getTopTags method and supplies the API key associated with the application. Methods are grouped into packages. This example, tag.getTopTags, is part of the tag package, which includes all calls related to user tags.
All of the calls that write data and a few of the user-specific read calls require user authentication. Your application can only make these kinds of requests on behalf of a registered Last.fm user. Last.fm exposes a user authentication API through its auth package.
The authentication mechanism varies from platform to platform, but the desktop and web mechanisms are similar. The basic idea for non-mobile devices is that your application obtains a short-lived token that is associated with a logged-in user and then uses this token to retrieve a long-lived session key from the
server. The session key allows you to make authenticated calls. Users authenticate on the Last.fm site, so your application never handles user credentials directly.
In addition to the session key, authenticated calls also require a method signature. The signature is a hash of the method and its parameters along with the shared secret that you received with the API key. The application must generate a method signature for each authenticated call.
Data for All
Most of the data you can pull from Last.fm does not require authentication. This includes information on artists, albums, tracks, and users that you can use for visualization, tracking, and comparison in your applications.
There are 12 packages in the main API, including auth. Most of these packages contain all the functions related to a certain entity type, such as a user or an artist. The packages are:
·
album Functions related to
albums, including text search.
·
artist Artist information, including
events, fans, and similar artists.
·
auth User authentication.
·
event Event information.
·
geo Location-based data on artists,
events, and tracks.
·
group Fetch charts associated with user
groups.
·
library Read or write artists, albums, and
tracks to a user library.
·
playlist Read, create, and add tracks to
playlists.
·
tag Tag functions, including getting
associated artists and tracks.
·
tasteometer Compares users and returns a
similarity score and shared artists.
·
track Track functions, including similar
tracks, ban, and love.
·
user User information.
Many of the
entity-type packages include sets of similar functions, such as getInfo or
search. For illustration, here is the full method list for the track package:
·
track.addTags Authenticated. Add a
tag for the track for the given user.
·
track.ban Authenticated.
"Ban" a track for a given user.
·
track.getInfo Get information
for the track, including artist and length of track.
·
track.getSimilar
Get tracks that are similar to this track.
·
track.getTags Authenticated. Get
tags for this track for the given user.
·
track.getTopFans Get top fans (users) for
this track.
·
track.getTopTags Get most frequently
assigned tags for this track.
·
track.love Authenticated.
"Love" a track for a given user.
·
track.removeTag Authenticated. Remove a
tag from this track.
·
track.search Text search for tag.
·
track.share Authenticated.
Share track with another user.
The
track.getTopFans and track.getTopTags methods are used to lookup related
entities, starting with a track. Similarly, you can use artist.getTopTracks to
look up the most popular tracks for an artist. Figure 1 is an illustration of
some of the methods that relate the main Last.fm entities to one another.
Figure
1. You can
navigate through the main entities in the Last.fm API through a series of
lookup methods.
Let's look at how you might use API calls to construct a simple application to find events
that might be of the most interest to a Last.fm user. This application would
not require authentication, although the user would have to enter his or her
username.
First, we might call user.getTopArtists, using the following URL:
http://ws.audioscrobbler.com/2.0/?method=user.gettopartists&user=xxx&api_key=xxx
This would return an XML document with a list of artists. The fragment below shows the top
of the document, through the first artist.
<?xml
version="1.0" encoding="utf-8"?>
<lfm
status="ok">
<topartists
user="xxx" type="overall">
<artist
rank="1">
<name>Squeeze</name>
<playcount>124</playcount>
<mbid>0509a681-a362-4800-9075-656041dccdbd</mbid>
<url>http://www.last.fm/music/Squeeze</url>
<streamable>1</streamable>
<image
size="small">http://userserve-ak.last.fm/serve/34/48192.jpg</image>
<image
size="medium">http://userserve-ak.last.fm/serve/64/48192.jpg</image>
<image size="large">http://userserve-ak.last.fm/serve/126/48192.jpg</image>
</artist>
<artist
rank="2">
...
The application parses the XML response to extract the list of artists. Then we can call artist.getEvents for each of the artists in the list:
http://ws.audioscrobbler.com/2.0/?method=artist.getevents&artist=Squeeze&api_key=xxx
And again, each call would return an XML response containing a list of events (if there are any scheduled) for the given artist. The application parses the XML to extract event information, and presents the list of events to the user.
Other Methods
These un-authenticated APIs are ideal for the kind of data exploration and analysis described above. Last.fm's authenticated APIs are for a different purpose, allowing you to develop user profile management applications. The authenticated APIs include calls for applying and removing tags, for working with the user library, and for creating and editing playlists. All of Last.fm's calls that write data to the server are authenticated.
One additional un-authenticated method deserving of specific mention is tasteometer.compare, the only method in the tasteometer package. tasteometer.compare takes as arguments two items to compare; the items must be either Last.fm users, Myspace users, or lists of artist names. The call returns a similarity score that reflects common musical "tastes" between the two users (or between a user and a set of artists). It also returns a list of artists that the two items have in common.
Last.fm bases its recommendations on songs that users listen to, whether through the Last.fm client software, through the web, or through portable devices. Third-party media players can scrobble track selections to Last.fm using the Last.fm submissions protocol and a separate web service based at
http://post.audioscrobbler.com:80/. The submission API is different from the rest of the Last.fm APIs, with its own authentication method and its own response formats. If you are developing a media player, you can get additional information on the submissions API and the submissions protocol at http://www.last.fm/api/submissions.
The Last.fm API provides applications with a vast set of data that links users with artists, tracks, events, and additional items. It's a unique resource for describing and defining musical taste. Developers can make the most of the Last.fm API by creating music and social-networking applications that deliver new ways to explore and present this data.
Resources:
1. How to consume REST services with WCF, Pedram Rezaei
2. Accessing Web Services in Silverlight, MSDN