C# Koha API Updates

 Koha  Comments Off
Jan 082013
 

I’ve updated the C# Koha API library that MarcEdit utilizes to include support for the item update when working with Koha version 3.8+.  Additionally, I added to the git repository a reference application that demonstrates how to use the library.  You’ll need to provide your own system and credentials to try it, but it should demonstrate how to make it all work together.

Git Hub Repository: https://github.com/reeset/koha_api

–tr

 Posted by at 11:27 am
Nov 282012
 

I’ve been spending the last week working with the Koha API, using it as an example for MarcEdit’s direct ILS integration platform.  After spending some time working with it and pushing some data through it, I have a couple of brief thoughts.

  1. I was pleasantly surprised as how easy the API was to work with.  Generally, the need for good authentication often stymies many a good API designs because the process for doing and maintaining authentication becomes so painful.  I found the cookejar approach that Koha implemented to be a very simple one to support and work with.  What’s more, error responses when working with the API tended to show up as HTTP Status codes, so it was easy to work with them using existing html tools.
  2. While the API is easy to use, it’s also really, really sparse.  There isn’t a facility for deleting records and I’m not sure if there is an easy way with the API to affect holdings for a set of records. I do know you can create items, but I’m not sure if that is a one off that occurs when you pass an entire bib record for update, or if there is a separate API that works just for Item data.  Search is also disappointing.  There is a specific API for retrieving individual records data – but the Search API is essentially Z39.50 (or SRU).  I’m not particularly enamored with either, though Z39.50 works (and I’m told that it’s fairly universal in terms of implementation).  I’ve never really liked SRU so it didn’t hurt my feelings too much to not work with it.  However, after spending time working with the Summon search API for other projects here at Oregon State, I was disappointed that search wasn’t something that the API specifically addressed.
  3. The API documentation leaves much to be desired.  I was primarily utilizing the Wiki (http://wiki.koha-community.org/wiki/Koha_/svc/_HTTP_API) which includes a single page on the API.  The page provided some simple demonstrations to show usage, which are really helpful.  What is less helpful is the lack of information regarding what happens when an error occurs.  The Authorization API returns an XML file with a status message – however, all other API return HTTP status codes.  This caught me a little by surprise, given the Authorization response – it would be nice if that information was documented somewhere.
  4. One thing that I can’t find in the documentation, so I really can’t answer this question is the impact of the API on system resources.  The API seems really to be geared towards working with individual records.  Well, MarcEdit is a batch records tool.  So, in my testing, I tried to see what would happen if I uploaded 1010 records through the API.  The process finished, sluggishly, but it appeared that uploading records through the API at high rates was having an impact on system performance.  The Upload process itself slowed considerably as the records were fed through the API.  But more curious – after the process finished, I had to wait about 15 minutes or so for all the records to make it through the workflow.  I’m assuming the API must queue items coming into the system, but this made it very difficult to test successful upload because the API was reporting success, but the data changes were not visible for a considerable amount of time.  Since I’ve never worked in a library that ran Koha in a production environment, I’m not sure if this type of record queuing is normal, but a better description of what is happening in the documentation would have been nice.  When I first started working with the API, I actually thought that the data updates were failing because I was expecting the changes to be in real-time in the system…my experience however seemed to indicate that they are not.

Anyway – those are my quick thoughts.  I need to caveat these notes by saying I have never worked at a library where Koha has been used in production, so maybe some of these behaviors are common knowledge.

 

–TR

 Posted by at 1:40 am
Nov 272012
 

One of the new features coming to MarcEdit is direct ILS integration.  Working with Koha as a proof of concept, the attached video demonstrates how users can utilize the MarcEditor to retrieve data directly from within their ILS system (using both single and batch searches).  This feature will be available to users around Dec. 1st-ish, 2012.

–tr

 Posted by at 3:16 am
Nov 242012
 

I’ve been tinkering with the Koha API to allow MarcEdit to do some direct ILS integration with Koha-based systems.  When I first agreed to look at doing this work, I wasn’t sure what the API looked like.  Fortunately for me, the folks that put it together made it simple and easy to work with.  There are a few gocha’s when working with C#, and while I’ll be posting the source code for the Koha library that I’ve developed in C# on my github account, I thought I’d post some of my initial notes for those that are interested.

Essentially, to work with the Koha API, there are two things that you need to have.  First, you need to authenticate yourself.  Upon authentication, Koha provides session data that is maintained as a cookie that must be passed as part of future requests to the API.  Generally, this process is straightforward, in that you create a cookiejar.  In C#, this looks like the following:

private bool Authorize()
        {
            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(var_host + "/cgi-bin/koha/svc/authentication?userid=" + var_user + "&password=" + var_pass);
            request.CookieContainer = cookieJar;

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

            System.IO.StreamReader reader = new System.IO.StreamReader(response.GetResponseStream(), Encoding.UTF8);
            string tmp = reader.ReadToEnd();

            //Add cookies to CookieJar (Cookie Container)
            foreach (Cookie cookie in response.Cookies)
            {
                cookieJar.Add(new Cookie(cookie.Name.Trim(), cookie.Value.Trim(), cookie.Path, cookie.Domain));
            }

            reader.Close();
            response.Close();

            if (tmp.IndexOf("ok") > -1)
            {
                return true;
            }
            else
            {
                return false;
            }
            
	}

The Cookie Jar in this case is scoped as global to the class, this way the session information doesn’t need to be regenerated unless the session expires.

Retrieving individual records is supported by the API. 

private string GetRecord(string id)
        {
            string uri = var_host + "/cgi-bin/koha/svc/bib/" + id + "?userid=" + var_user + "&password=" + var_pass;
            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(uri);
            request.CookieContainer = cookieJar;

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

            System.IO.StreamReader reader = new System.IO.StreamReader(response.GetResponseStream(), Encoding.UTF8);
            string tmp = reader.ReadToEnd();
            
            reader.Close();
            response.Close();

            return tmp;
        }

In the case of Koha, the GetRecord function returns data in MARCXML format. This is my preferred method for retrieving data, but for general search and retrieval, while Koha supports SRU, the most reliable search API is still Z39.50 (sadly).

Finally, when you want to update or create a new record, you need to push the data up to the server in MARCXML format.  If the data is an update, you pass a record id, if it’s a new record, you don’t.

private bool UpdateRecord(string rec) 
	{
   	     return UpdateRecord(rec, null);
	}

private bool UpdateRecord(string rec, string id)
        {
            string uri = "";
 	    if (id == null) {
                uri = var_host + "/cgi-bin/koha/svc/new_bib?userid=" + var_user + "&password=" + var_pass;
            } else {
  	        uri = var_host + "/cgi-bin/koha/svc/bib/" + id + "?userid=" + var_user + "&password=" + var_pass;
 	    }
            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(uri);
            request.CookieContainer = cookieJar;
            request.Method = "POST";
            request.ContentType = @"text/xml";
            System.IO.StreamWriter writer = new System.IO.StreamWriter(request.GetRequestStream(), System.Text.Encoding.UTF8);
            writer.Write(rec);
            writer.Flush();
            writer.Close();
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();

            System.IO.StreamReader reader = new System.IO.StreamReader(response.GetResponseStream(), Encoding.UTF8);
            string tmp = reader.ReadToEnd();

            reader.Close();
            response.Close();

            return true;

        }

And that’s pretty much it. Simple and straightforward. Koha supports a few more API (http://wiki.koha-community.org/wiki/Koha_/svc/_HTTP_API, but for my immediate purposes, these are the couple that I need to support some very simple integration with the ILS. Ideally, at some point, it would be nice to see these API also support automated deletion of records, as well as maybe an ability to set holdings/items — but for now, this is good enough. I’m sure if these other functions are needed, the communities themselves will push for them within their own user communities and when they show up, MarcEdit will indirectly benefit.

–TR

 Posted by at 2:39 am