views:

53

answers:

2

Ok I am programing a way to interface with Grooveshark (http://grooveshark.com). Right now I have a class Grooveshark and several methods, one gets a session with the server, another gets a token that is based on the session and another is used to construct api calls to the server (and other methods use that). Right now I use it like so.... Note uses twisted and t.i.defer in twisted

g = Grooveshark()
d = g.get_session()
d.addCallback(lambda x: g.get_token())
## and then something like.... ##
g.search("Song")

I find this unpythonic and ugly sense even after initializing the class you have to call two methods first or else the other methods won't work. To solve this I am trying to get it so that the method that creates api calls takes care of the session and token. Currently those two methods (the session and token methods) set class variables and don't return anything (well None). So my question is, is there a common design used when interfacing with sites that require tokens and sessions? Also the token and session are retrieved from a server so I can't have them run in the init method (as it would either block or may not be done before a api call is made)

+2  A: 

I find this unpythonic and ugly sense even after initializing the class you have to call two methods first or else the other methods won't work.

If so, then why not put the get_session part in your class's __init__? If it always must be performed before anything else, that would seem to make sense. Of course, this means that calling the class will still return a yet-unusable instance -- that's kind of inevitable with asynchronous, event-drive programming... you don't "block until the instance is ready for use".

One possibility would be to pass the callback to perform as an argument to the class when you call it; a more Twisted-normal one would be to have Grooveshark be a function which returns a deferred (you'll add to the deferred the callback to perform, and call it with the instance as the argument when that instance is finally ready to be used).

Alex Martelli
Ok thanks, so basically it is an asynchronous factory? Also the get_session and get_token are contacting a server so they aren't functions I can depend on being done in any sort of speed
Zimm3r
@Zimm3r, of course not -- that's why I suggest either a simplistic approach (which goes against the grain of Twisted;-) of passing the callback directly when you call the class, or, better, not calling the class but a factory function which returns a deferred (if that's what you mean by "async factory", then it's definitely one;-).
Alex Martelli
"Of course, this means that calling the class will still return a yet-unusable instance -- that's kind of inevitable with asynchronous, event-drive programming..." Not necessarily. If you want the session setup to be transparent, you can make it transparent. The fact that the other methods (like search) already return a Deferred means that the caller likely won't even notice if the result has to wait for session setup to complete.In other words search and the other methods should just wait on the get_session Deferred which either they should call internally or which __init__ should call.
Jean-Paul Calderone
Ok thanks that was what I was thinking of doing (internally taking care of the session and token if they needed to be updated). Course that brings up the question; should get_session and get_token set self.session and self.token respectively and get_token reference self.session (the token needs the session) or should get_session return session (and have the callbacks take care of setting the instance var) and get_token take an argument or reference self.session. Maybe I should make a new question.
Zimm3r
@Zimm, yes, I do think that a new question would be better than confining the new design discussion into a comment thread (esp. if JP Calderone, a real Twisted guru, can respond on that one!-).
Alex Martelli
@Jean-Paul, excellent point, thanks, +1!
Alex Martelli
A: 

I would highly recommend looking at the Facebook graph API. Just because you need sessions and some authentication doesn't mean you can build a clean REST API. Facebook uses OAuth to handle the authentication but there are other possibilities.

Zach Bialecki