Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python urllib2, basic HTTP authentication, and tr.im

I'm playing around, trying to write some code to use the tr.im APIs 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?

like image 439
Daryl Spitzer Avatar asked Mar 11 '09 15:03

Daryl Spitzer


People also ask

What does urllib2 do in Python?

urllib2 is a Python module that can be used for fetching URLs. The magic starts with importing the urllib2 module.

What is the difference between Urllib and urllib2?

1) urllib2 can accept a Request object to set the headers for a URL request, urllib accepts only a URL. 2) urllib provides the urlencode method which is used for the generation of GET query strings, urllib2 doesn't have such a function. This is one of the reasons why urllib is often used along with urllib2.

Is urllib2 deprecated?

urllib2 is deprecated in python 3. x. use urllib instaed.

Does urllib2 work in Python 3?

NOTE: urllib2 is no longer available in Python 3 You can get more idea about urllib.


1 Answers

This seems to work really well (taken from another thread)

import urllib2, base64  request = urllib2.Request("http://api.foursquare.com/v1/user") base64string = base64.encodestring('%s:%s' % (username, password)).replace('\n', '') request.add_header("Authorization", "Basic %s" % base64string)    result = urllib2.urlopen(request) 
like image 74
Ben Keating Avatar answered Sep 19 '22 06:09

Ben Keating