views:

2688

answers:

1

I'm playing around, trying to write some code to use the http://tr.im APIs (http://tr.im/api/) to shorten a URL.

After reading http://docs.python.org/library/urllib2.html, I tried:

   TRIM_API_URL = 'http://api.tr.im/api'
   auth_handler = urllib2.HTTPBasicAuthHandler()
   auth_handler.add_password(realm='tr.im',
                             uri=TRIM_API_URL,
                             user=USERNAME,
                             passwd=PASSWORD)
   opener = urllib2.build_opener(auth_handler)
   urllib2.install_opener(opener)
   response = urllib2.urlopen('%s/trim_simple?url=%s'
                              % (TRIM_API_URL, url_to_trim))
   url = response.read().strip()

response.code is 200 (I think it should be 202). url is valid, but the basic HTTP authentication doesn't seem to have worked, because the shortened URL isn't in my list of URLs (at http://tr.im/?page=1).

After reading http://www.voidspace.org.uk/python/articles/authentication.shtml#doing-it-properly I also tried:

   TRIM_API_URL = 'api.tr.im/api'
   password_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
   password_mgr.add_password(None, TRIM_API_URL, USERNAME, PASSWORD)
   auth_handler = urllib2.HTTPBasicAuthHandler(password_mgr)
   opener = urllib2.build_opener(auth_handler)
   urllib2.install_opener(opener)
   response = urllib2.urlopen('http://%s/trim_simple?url=%s'
                              % (TRIM_API_URL, url_to_trim))
   url = response.read().strip()

But I get the same results. (response.code is 200 and url is valid, but not recorded in my account at http://tr.im/.)

If I use query string parameters instead of basic HTTP authentication, like this:

   TRIM_API_URL = 'http://api.tr.im/api'
   response = urllib2.urlopen('%s/trim_simple?url=%s&username=%s&password=%s'
                              % (TRIM_API_URL,
                                 url_to_trim,
                                 USERNAME,
                                 PASSWORD))
   url = response.read().strip()

...then not only is url valid but it's recorded in my tr.im account. (Though response.code is still 200.)

There must be something wrong with my code though (and not tr.im's API), because

$ curl -u yacitus:xxxx http://api.tr.im/api/trim_url.json?url=http://www.google.co.uk

...returns:

{"trimpath":"hfhb","reference":"nH45bftZDWOX0QpVojeDbOvPDnaRaJ","trimmed":"11\/03\/2009","destination":"http:\/\/www.google.co.uk\/","trim_path":"hfhb","domain":"google.co.uk","url":"http:\/\/tr.im\/hfhb","visits":0,"status":{"result":"OK","code":"200","message":"tr.im URL Added."},"date_time":"2009-03-11T10:15:35-04:00"}

...and the URL does appear in my list of URLs on http://tr.im/?page=1.

And if I run:

$ curl -u yacitus:xxxx http://api.tr.im/api/trim_url.json?url=http://www.google.co.uk

...again, I get:

{"trimpath":"hfhb","reference":"nH45bftZDWOX0QpVojeDbOvPDnaRaJ","trimmed":"11\/03\/2009","destination":"http:\/\/www.google.co.uk\/","trim_path":"hfhb","domain":"google.co.uk","url":"http:\/\/tr.im\/hfhb","visits":0,"status":{"result":"OK","code":"201","message":"tr.im URL Already Created [yacitus]."},"date_time":"2009-03-11T10:15:35-04:00"}

Note code is 201, and message is "tr.im URL Already Created [yacitus]."

I must not be doing the basic HTTP authentication correctly (in either attempt). Can you spot my problem? Perhaps I should look and see what's being sent over the wire? I've never done that before. Are there Python APIs I can use (perhaps in pdb)? Or is there another tool (preferably for Mac OS X) I can use?

+3  A: 

Really cheap solution:

urllib.urlopen('http://user:[email protected]/api')

(which you may decide is not suitable for a number of reasons, like security of the url)

Ali A
Are there any advantages to this over using query string parameters?
Daryl Spitzer
Daryl: if it works, I would say that it's an advantage yes, and probably more secure than query string arguments as most http clients are a bit more careful about how they handle them.
Ali A
I'll probably go with this (so you get my upvote), but I'd still like to figure out what's wrong with my code (so this won't be my accepted answer).
Daryl Spitzer
This returns an error... InvalidURL: nonnumeric port: '[email protected]/api'
nbolton