Goodreads API
I consider myself a positive person. In my private life I'm pretty much always doing some kind of prank and laughing pretty out loud with my friends. It is necessary a substantial amount of crap to piss me off. Nevertheless from time to time it happens, unfortunately, that I stumble upon something that really, really mess with my Buddhist psychic status. This weekend I purpose myself, as a pet project, to create a python utility to extract information of my ereader and to put the extracted information into my goodreader acoount. High level speaking what it would be needed is
- Extract information about reading status from the ereader, which means scrap the information out of a SQLite database
- Use the extract data and upload into the goodreader service the new stuff
- Implement the client for the goodreader service
Ironically I start by doing the last of this three items. I gave a quick overview during this week and it seemed that this would be a simple work. So lets start with the most simple stuff first. Lets call it Simple Stuff Development or SSD (why not, if others can invent names, why can't I?). So, with this in mind I start to look for already implemented libraries that could help me get the job done. I search in pip repositories and find one called (guess what) goodreads. I start by exploring this and when I was trying to create a review I found that all of the methods, other than http get, weren't implemented. What? Yes, what? How's that. What's the point of implement only the calls that aren't OAuth. At first I tried a workaround that would help me use what is implemented, plus all the OAuth based calls, but then I start looking into the library and didn't like it. More, it encapsulates the low level communication in a way that I didn't like. Well this pretty much pushed me to begin my own implementation of a goodreads api client. But, back to the beginning. What was that that really piss me off? Things like this:
Add book reviews for members using OAuth.
You'll need to register your app (required).
URL: https://www.goodreads.com/review.xml
HTTP method: POST
Parameters:
book_id: Goodreads book_id (required)
review[review]: Text of the review (optional)
review[rating]: Rating (0-5) (optional,
default is 0 (No rating))
review[read_at]: Date (YYYY-MM-DD format,
e.g. 2008-02-01) (optional)
shelf:
read|currently-reading|to-read|
<USER SHELF NAME>
(optional, must exist, see: shelves.list)
First of all not even a web interface to create the OAuth token request. Yes, to create the oauth request for your application you need to do something like this which is basically applying the OAuth API to the creation of a application request token. This sucks. This should be provided as a website functionality as is done with twitter and facebook platforms. Then the thing that most irritates me is that the names adopted for the variables. When you see things like this
book_id: Goodreads book_id (required)
review[review]: Text of the review (optional)
review[rating]: Rating (0-5) (optional, default is 0 (No rating))
You are induced to think that review[review] means something like this review.review in object notation. So my first interpretation for the set of parameters was the following
{
'book_id': 'bookID',
'review' : {
'review' : 'review of the book',
'rating' : 4,
'shelf' : 'read'
}
}
Which is a pretty common interpretation of the representation of the parameters. So I lost a fair amount of time to discover that the representation is as follows
{
'book_id': 'bookID',
'review[review]' : 'review of the book',
'review[rating]' : 4,
'review[shelf]' : 'read'
}
}
Yes, the keys have a dictionary access representation. Who creates an API like this? What are they thinking when they do names like this to the variables? Not an even page acknowledging for the fact that this may create an ambiguity and therefore an example how this should be interpreted?
Then, like if this wasn't bad enough, I start noticing that the server responded with http 500 error code reporting for a Internal error. Oh thanks you've got an error while processing my request, but Mr Server, it is possible to give me a little more of detail about what just happen? So the error handling is pretty much inexistent and the API client is completly in the dark when things go wrong. But in all of this mud the worst thing is the lack of examples of requests, mainly for those regarding PUT and POST operations.