Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / XML

Unraveling the Netflix API - Part IV - Managing User Account Information

5.00/5 (2 votes)
28 Feb 2010CPOL15 min read 39.2K   387  
Demonstrates how to manage a Netflix subscriber's movie queue
Netflix Application Example

Contents

Introduction

In the previous article in this series, I showed you how to access a Netflix subscriber's account information. In that article, I provided a sample application that enabled you to explore a Netflix subscriber's account information. One of the resources that you may have visited with the explorer is the subscriber's movie queue, representing a list of DVDs that the subscriber has assembled for rental viewing. This article will demonstrate one aspect of managing a subscriber's account information by showing you how to add, move, and delete titles from a subscriber's movie queue.

Background

This article will show you how to:

  • Obtain and use the movie titles in a subscriber's queue
  • Add, delete, and move titles around in the subscriber's queue

Querying the Subscriber's Movie Queue

The first step in managing a subscriber's movie queue is to obtain the queue list. Again, you may have found this list through the use of the Account Explorer example application from the previous article. The resource location is:

http://api.netflix.com/user/{user_identity}/queues/disk

Where {user_identity} is the identifier for a subscriber that you received in an account access authorization response. The subscriber queue information is obtained by submitting a protected request for this resource.

Parsing the Queue Information

The XML document returned in the response for a queue information request is a queue object that contains, among other things, a collection of queue_item objects. It may not be a surprise that the contents of a queue_item object are very similar to a catalog_title object that is returned in a title search (as described in the second article in this series). The only difference between the two is that the queue_item object contains additional information about the title as it relates to the subscriber's queue: position in the queue, title availability, when the item was last updated in the queue, and so on. To make a long story short, the following code shows the changes that were made to the CatalogTitle data container class in the NetflixParser module to accommodate the additional data contained in the queue_item objects.

C#
/// <summary>
/// General purpose container for title information
/// </summary>
public class CatalogTitle
{
    // only for catalog titles
    public int rank;    // this is for our own use in ordering the search results

    // these are specific to queue items
    public int position;
    public string category; // actually represents availability
    public DateTime availability;
    public DateTime updated;

    // common to catalog titles and queue items
    public string idUrl;    // fully qualified URL to retrieve title details
    public string ID;       // title ID stripped from idUrl
    public TitleName title;
    public BoxArt cover;
    public string year;
    public string runtime;
    public string avg_rating;
    public List<Category> categories;
    public Dictionary<string, Link> links;

    // for title expansions (just a few examples)
    public string synopsis;
    public Dictionary<string, Link> cast;
    public Dictionary<string, Link> directors;
}

Additional changes were made to the parser code to handle the new elements contained in the queue_item objects. One particular change of note is the category item. The original catalog_title objects contain category objects that only have attributes associated with them. However, there is a category object in the queue_item that contains both attributes and a value. There is only one such object in the queue_item object and so its value is stored in a discrete data item, as shown in the above code snippet.

Two new parser interfaces were written to support parsing the subscriber queue information:

  • ParseQueueItems parses the entire contents of the XML document returned by a request for the subscriber's queue information. This returns a list of queue_item objects, represented as the (now extended) CatalogTitle data objects, and the value of the etag element that represents the queue state - I'll elaborate more on this when we get to the queue update discussion.
  • QueueItemInfo parses an individual queue_item object.

I won't go into the details of the changes to the parsing functions because these should be quite obvious in the code. An addition to the NetflixParser module is two helper functions:

  • StripHtml was incorporated from the title catalog explorer application.
  • ConvertTimestap was added to convert the UNIX timestamp format that Netflix uses into a .NET DateTime object.

Making Update Requests

As with a number of aspects of the Netflix documentation, and the primary reason why I've written this series of articles, I found the Netflix description of how to submit change request quite lacking in specifics. According to the Netflix API documentation, they support four HTTP methods, which correspond to the four basic data storage functions:

HTTP MethodEquivalent Operation
POSTCreate
GETRead
PUTUpdate
DELETEDelete

I have found, however, that the HTTP PUT method does not seem to be supported quite as expected, even though it is referenced in a few places in the Netflix API documentation. It turns out that which HTTP method should be used for a given operation is not necessarily intuitive, as will be demonstrated when I explain why moving a title in a queue uses a POST rather than a PUT further along in this article. Also, as a point of interest, there is an alternate way of using the POST method to perform a delete operation. This is described shortly when I go into the implementation details.

Netflix Request Changes

Up until now, all of the Netflix service request have been queries, using the default HTTP GET method. To use other HTTP methods for service requests, the following changes were made to the NetflixRequest class:

  1. Two new overloaded protected requests were added that allow for the specification of the HTTP method. Like the existing pairs of request methods, one of these returns an XML string and the other returns an XmlDocument object.
  2. The common function for creating the Protected service requests was modified to accept the HTTP method. The HTTP method is a required parameter for constructing a signed request signature.
  3. A new pair of common service request overloads were created, one using a default HTTP GET method and the other allowing for the specification of the HTTP method.

These changes were not required for the Non-Authorized and Signed requests, which will only ever use the GET method.

Note: The Netflix API documentation does indicate that there may be cases where a request can exceed the nominal 256 character limit imposed by a GET method. While this claim has been debunked as a myth, Netflix does support using the POST method in requests where you would normally use the GET.

Update Request Implementation

You may recall that I mentioned earlier that the ParseQueueItems method in the NetflixParser class returns, in addition to a list of titles in the subscriber's queue, an element called the etag. This element contains an opaque value that represents a synchronization state of the data that you have received from Netflix. The purpose of this tag is for concurrency control, that is to say to verify that the database has not changed between the time you received a set of information and the time you submitted a request to modify it. The content of this element has meaning only to the Netflix service, hence it is considered opaque. If you submit a request with a missing, or out of date, etag you will receive an error response indicating that you must synchronize with the database. Therefore, all update requests must include a valid etag in the query string parameters.

In this article, the example used is making changes to a subscriber's DVD queue. For this purpose, the following bit of example code demonstrates preparing a NetflixRequest object for a Protected service request, setting the target endpoint to the subscriber's DVD queue, and adding the etag parameter to the request.

C#
NetflixRequest request = new NetflixRequest(txtKey.Text, txtSecret.Text,
                                            _auth.Token, _auth.Secret);
string requestUrl = "http://api.netflix.com/users/" + _auth.UserID + "/queues/disc";
request.AddQueryParameter("etag", _etag);
//...update-specific operations follow...

Title Add Operation

Adding a title to the subscriber's queue requires only two items of information: the title identifier and, optionally, the position at which to insert the title in the queue. If the position is not specified, then the title is added to the end of the subscriber's queue. I have already covered the mechanics of searching for a title and obtaining its identity in the Netflix Catalog Explorer example in the second article in this series, so I won't go into that again here. The code snippet below shows an example of adding these two parameters to a request that will add the movie "Casper" to a subscriber's queue at position 13.

C#
NetflixRequest request = new NetflixRequest(txtKey.Text, txtSecret.Text,
                                            _auth.Token, _auth.Secret);
string requestUrl = "http://api.netflix.com/users/" + _auth.UserID + "/queues/disc";
request.AddQueryParameter("etag", _etag);
request.AddQueryParameter("title_ref", 
	"http://api.netflix.com/catalog/titles/movies/60030118");
request.AddQueryParameter("position", "13");
XmlDocument xDoc = request.ProtectedRequestXml(requestUrl, "POST");

Title Move Operation

Moving a title in the subscriber's queue is virtually identical to adding a new title, with the exception that the title already exists in the subscriber's queue. One difference is that if you wish to move the title to the end of the queue, you must place it there explicitly, rather than not including the position parameter in the request as in the Add request. The following code snippet shows an example of setting the parameters for moving a title to the end of the subscriber's queue, where lvQueue is the ListView control used in the example code accompanying this article.

C#
NetflixRequest request = new NetflixRequest(txtKey.Text, txtSecret.Text,
                                            _auth.Token, _auth.Secret);
string requestUrl = "http://api.netflix.com/users/" + _auth.UserID + "/queues/disc";
request.AddQueryParameter("etag", _etag);
request.AddQueryParameter("title_ref", 
	"http://api.netflix.com/catalog/titles/movies/60030118");
request.AddQueryParameter("position", 
	lvQueue.Items.Count.ToString());  // move to end of queue
XmlDocument xDoc = request.ProtectedRequestXml(requestUrl, "MOVE");

Note: The position value must be 1 or greater, and if not specified the title will be added to the end of the subscriber's queue.

As previously noted, although it would seem that the proper HTTP method for adding a title is "PUT", the service rejects this action in this context. The Netflix support team explains this by stating that moving a title in a queue actually creates the title entry in the queue at a new location, which consequently overrides its previous position because there can be only one instance of a title in a given queue.

In order to differentiate a title creation from a movement, I added a pseudo-method of "MOVE". This differentiation is required in order to provide the proper behavior when the new queue position, which is optional, is not provided. See the source code for the implementation details.

Title Delete Operation

Lastly, deleting a title from the subscriber's queue is slightly different from the previous two operations, but still quite simple. In this case, the URI for the title to be removed from the queue must point specifically to the available titles queue. In addition, the HTTP DELETE method is specified for the Protected request. The following code snippet illustrates the parameters required for removing a title from the subscriber's movie queue:

C#
NetflixRequest request = new NetflixRequest(txtKey.Text, txtSecret.Text,
                                            _auth.Token, _auth.Secret);
string requestUrl = "http://api.netflix.com/users/" + _auth.UserID + "/queues/disc";
requestUrl += "/available/" + title.ID;
request.AddQueryParameter("etag", _etag);
XmlDocument xDoc = request.ProtectedRequestXml(requestUrl, "DELETE");

Note that in this example, the HTTP request method is specified as DELETE. An alternative that the Netflix API allows is to specify the HTTP POST method and also adding a method query parameter set to delete, as shown in the following equivalent example:

C#
NetflixRequest request = new NetflixRequest(txtKey.Text, txtSecret.Text,
                                            _auth.Token, _auth.Secret);
string requestUrl = "http://api.netflix.com/users/" + _auth.UserID + "/queues/disc";
requestUrl += "/available/" + title.ID;
request.AddQueryParameter("etag", _etag);
request.AddQueryParameter("method", "delete");
XmlDocument xDoc = request.ProtectedRequestXml(requestUrl, "POST");

The stated reason for this alternative is for testing purposes using a Web browser, in which you might not be able to specify the HTTP request method. Another possible reason, although not specifically stated in the documentation, may be that not all HTTP code libraries might support the full set of HTTP methods, whereas you can always count on support for GET and POST.

Example Application

Code Features and Tips for Enhancements

One of the things you might notice in this example application is that I have relocated all of the Netflix supporting modules into a NetflixAPI namespace. I did this as a first step towards consolidating all of this code into a self contained library module, which, I'm sorry to say, is beyond the scope of these articles. But at least I've given you a hint for where you might take my code examples from here.

Throughout this entire series, I have used the most simple means of performing synchronous HTTP service requests. A change you might consider, if you choose to build on the example code I've provided, is to make the calls asynchronous so that the user is not subjected to the annoying application wait cursor while the request is pending completion. Be sure to read my comments about this in the conclusion of this article.

Program Startup

The program requires the account access authorization tokens that were the subject of the previous article. For the sake of simplicity, I have not included the code for obtaining these tokens in this example. Instead, you must copy the accessInfo.xml token container file that was created by the Netflix Account Explorer example application to where this article's example program is executing.

Netflix Application Example

After passing the account access authorization check, you enter your Netflix developer consumer key and secret and then click Q, which loads the ListView control with the titles in the subscriber's queue of available titles.

Netflix Application Example

Note: The example code has set the max_results option in the service request to 100 (the maximum allowed by the Netflix API), overriding the default value of 25. You might consider retrieving the information in the subscriber's queue in smaller chunks, or you will have to if the number of items in the subscriber's queue exceeds 100. You do this by utilizing the number_of_results value returned in the response to determine the total number of chunks needed, and the start_index option in conjunction with the max_results option the request to retrieve selected chunks of data. This technique may be also be employed to provide progress information to the user of the application where very large blocks of data are being requested, and also reduces the impact to the application operation should a request fail.

After the subscriber's queue titles are loaded, right-clicking on any item in the list pops up a context menu that allows you to choose from three options - add a new title to the queue, move an existing title from one position in the queue to another, or remove an item from the queue.

Netflix Application Example

Adding a Title to the Queue

When Add is selected from the context menu, a dialog form is launched that allows you to search for a title to add to the queue. You may recognize this form as the main application form from the Catalog Explorer application in Part II of this series. You simply type a title, or partial title, to search for and click Search to obtain a set of search results.

Netflix Application Example

Note that in the previous screenshot the Add button is disabled. It remains disabled until a title has been selected from the results list, as shown in the next illustration:

Netflix Application Example

The application notes the position in the queue where the mouse cursor was located when the right-click that brought up the context menu occurred and uses this as the default insertion location for the new title. This form also provides the option of inserting the title at either the top or the end of the subscriber's queue. Clicking Add returns the information to the main application where the queue update operation is executed.

Moving a Title in the Queue

When Move is selected from the context menu, a dialog form is launched that allows you to change the position of a title in the queue. As in the Add operation, the location of the mouse cursor in the queue list is captured and displayed as the current and new queue positions for the selected title.

Netflix Application Example

The NumericUpDown control is used to set the new location for the title in the queue, and there are also options to simply move the title to the top or the end of the queue. The following illustration shows an example of moving the selected title to the beginning of the subscriber's queue.

Netflix Application Example

Clicking OK returns the information to the main application where the queue update operation is executed.

Deleting a Title from the Queue

Removing a title from the queue is much easier than the previous operations. All that is required is a simple MessageBox prompt that allows the user to confirm or reject the delete action.

Netflix Application Example

Clicking Yes returns the confirmation to the main application where the queue update operation is executed.

Conclusion

This article has described and demonstrated how to access the titles in a subscriber's queue, and how to manage the entries in that queue. This is only one of the features of a subscriber account that you can manipulate with the Netflix APIs. The documentation gives you all the details about the damage, er... I mean clever things, you can do to a subscriber's account with updates.

Afterword

This is the last article in this series and I hope they have been helpful. I hope that this has given you a good start and that you are beginning to think of some ideas for a great Netflix application of your own now that you understand the basics. As I ride off into the sunset, I will leave you with a few final pointers that you might keep in mind as you write your own Netflix applications.

  • As I've mentioned several times in these articles, the code examples use synchronous HTTP requests. In simple terms, this means the application waits until the request (and response) has completed before continuing execution. Now you might consider running these requests in another thread or using asynchronous requests in order to download bulk data. However, you should be aware that Netflix limits client applications to no more than four requests per second.
  • Speaking of limits, you should also keep in mind the following limits:
    • Signed requests are limited to 5,000 per day.
    • Protected requests are limited to 5,000 per day, per subscriber account.
    • The maximum number of results you can request using the max_results parameter is 100. If you are dealing with large amounts of data, you need to request it in chunks, using the start_index parameter.
  • I've taken the liberty to call all of my example applications "Netflix"-something-or-other. It is strictly forbidden to use "Netflix" as the first word in an application name. You should read the Netflix Branding Requirements for guidelines before choosing a name for your application.

History

  • September 5, 2009
    • Original submission
  • September 8, 2009 
    • Updated source code
  • February 25, 2010 
    • Corrected reversed functionality of PUT and POST actions in the HTTP Method table
    • Provided additional clarification about the POST action when used for moving titles in the queue

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)