At work I’m using Python 2.4.6 and wanted to play around with some of the Google API’s like Buzz and Moderator. Things didn’t quite work out-of-the-box so I thought I’d document my steps here for future reference and in the event anyone else might find it useful.
First, I read over the Python Google API page and found that in order to grab the code I’d first need to install Mercurial.
SteveT:cc strefethen$ sudo port install mercurial ---> Computing dependencies for mercurial ---> Dependencies to be installed: curl-ca-bundle python26 db46 gdbm sqlite3 ---> Fetching curl-ca-bundle ---> Attempting to fetch curl-7.21.2.tar.bz2 from http://distfiles.macports.org/curl ---> Attempting to fetch certdata-1.70.txt from http://distfiles.macports.org/curl ---> Verifying checksum(s) for curl-ca-bundle ---> Extracting curl-ca-bundle ---> Applying patches to curl-ca-bundle ---> Configuring curl-ca-bundle ---> Building curl-ca-bundle ---> Staging curl-ca-bundle into destroot ---> Installing curl-ca-bundle @7.21.2_4 ---> Activating curl-ca-bundle @7.21.2_4 ---> Cleaning curl-ca-bundle ---> Fetching db46 ---> Attempting to fetch patch.220.127.116.11 from http://distfiles.macports.org/db4/4.6.21_6 ---> Attempting to fetch patch.18.104.22.168 from http://distfiles.macports.org/db4/4.6.21_6 ---> Attempting to fetch patch.22.214.171.124 from http://distfiles.macports.org/db4/4.6.21_6 ---> Attempting to fetch patch.126.96.36.199 from http://distfiles.macports.org/db4/4.6.21_6 ---> Attempting to fetch db-4.6.21.tar.gz from http://distfiles.macports.org/db4/4.6.21_6 ---> Verifying checksum(s) for db46 ---> Extracting db46 ---> Applying patches to db46 ---> Configuring db46 ---> Building db46 ---> Staging db46 into destroot ---> Installing db46 @4.6.21_6 ---> Activating db46 @4.6.21_6 ---> Cleaning db46 ---> Fetching gdbm ---> Attempting to fetch gdbm-1.8.3.tar.gz from http://mirrors.kernel.org/gnu/gdbm ---> Verifying checksum(s) for gdbm ---> Extracting gdbm ---> Configuring gdbm ---> Building gdbm ---> Staging gdbm into destroot ---> Installing gdbm @1.8.3_3 ---> Activating gdbm @1.8.3_3 ---> Cleaning gdbm ---> Fetching sqlite3 ---> Attempting to fetch sqlite-autoconf-3070400.tar.gz from http://distfiles.macports.org/sqlite3 ---> Attempting to fetch sqlite-autoconf-3070400.tar.gz from http://www.sqlite.org/ ---> Verifying checksum(s) for sqlite3 ---> Extracting sqlite3 ---> Applying patches to sqlite3 ---> Configuring sqlite3 ---> Building sqlite3 ---> Staging sqlite3 into destroot ---> Installing sqlite3 @3.7.4_0 ---> Activating sqlite3 @3.7.4_0 ---> Cleaning sqlite3 ---> Fetching python26 ---> Attempting to fetch Python-2.6.6.tar.bz2 from http://distfiles.macports.org/python26 ---> Verifying checksum(s) for python26 ---> Extracting python26 ---> Applying patches to python26 ---> Configuring python26 ---> Building python26 ---> Staging python26 into destroot ---> Installing python26 @2.6.6_1 ---> Activating python26 @2.6.6_1 To fully complete your installation and make python 2.6 the default, please run: sudo port install python_select sudo python_select python26 ---> Cleaning python26 ---> Fetching mercurial ---> Attempting to fetch mercurial-1.7.3.tar.gz from http://distfiles.macports.org/python ---> Attempting to fetch mercurial-1.7.3.tar.gz from http://mercurial.selenic.com/release/ ---> Verifying checksum(s) for mercurial ---> Extracting mercurial ---> Configuring mercurial ---> Building mercurial ---> Staging mercurial into destroot ---> Installing mercurial @1.7.3_0 ---> Activating mercurial @1.7.3_0 ---> Cleaning mercurial
As you can see after a fairly lengthy install I was ready to grab the API sources:
SteveT:work strefethen$ hg clone https://google-api-python-client.googlecode.com/hg/ google-api-python-client requesting all changes adding changesets adding manifests adding file changes added 153 changesets with 468 changes to 204 files updating to branch default 172 files updated, 0 files merged, 0 files removed, 0 files unresolved</pre> <p>Next, was to setup the Google API python client</p> <pre class="brush: bash;">SteveT:work strefethen$ cd google-api-python-client/ SteveT:google-api-python-client strefethen$ sudo python setup.py install Password: Installing the following packages: 'apiclient', 'apiclient.ext', 'uritemplate' Loaded setuptools running install Checking .pth file support in /Users/strefethen/Library/Python2.4/site-packages/ /opt/local/bin/python -E -c pass TEST PASSED: /Users/strefethen/Library/Python2.4/site-packages/ appears to support .pth files running bdist_egg running egg_info creating google_api_python_client.egg-info writing google_api_python_client.egg-info/PKG-INFO writing top-level names to google_api_python_client.egg-info/top_level.txt writing dependency_links to google_api_python_client.egg-info/dependency_links.txt writing manifest file 'google_api_python_client.egg-info/SOURCES.txt' reading manifest file 'google_api_python_client.egg-info/SOURCES.txt' writing manifest file 'google_api_python_client.egg-info/SOURCES.txt' installing library code to build/bdist.macosx-10.6-i386/egg running install_lib running build_py creating build creating build/lib creating build/lib/apiclient copying apiclient/__init__.py -> build/lib/apiclient copying apiclient/anyjson.py -> build/lib/apiclient copying apiclient/discovery.py -> build/lib/apiclient copying apiclient/errors.py -> build/lib/apiclient copying apiclient/http.py -> build/lib/apiclient copying apiclient/model.py -> build/lib/apiclient copying apiclient/oauth.py -> build/lib/apiclient creating build/lib/apiclient/ext copying apiclient/ext/__init__.py -> build/lib/apiclient/ext copying apiclient/ext/appengine.py -> build/lib/apiclient/ext copying apiclient/ext/authtools.py -> build/lib/apiclient/ext copying apiclient/ext/django_orm.py -> build/lib/apiclient/ext creating build/lib/uritemplate copying uritemplate/__init__.py -> build/lib/uritemplate creating build/lib/apiclient/contrib creating build/lib/apiclient/contrib/buzz copying apiclient/contrib/buzz/future.json -> build/lib/apiclient/contrib/buzz creating build/lib/apiclient/contrib/latitude copying apiclient/contrib/latitude/future.json -> build/lib/apiclient/contrib/latitude creating build/lib/apiclient/contrib/moderator copying apiclient/contrib/moderator/future.json -> build/lib/apiclient/contrib/moderator creating build/bdist.macosx-10.6-i386 creating build/bdist.macosx-10.6-i386/egg creating build/bdist.macosx-10.6-i386/egg/apiclient copying build/lib/apiclient/__init__.py -> build/bdist.macosx-10.6-i386/egg/apiclient copying build/lib/apiclient/anyjson.py -> build/bdist.macosx-10.6-i386/egg/apiclient creating build/bdist.macosx-10.6-i386/egg/apiclient/contrib creating build/bdist.macosx-10.6-i386/egg/apiclient/contrib/buzz copying build/lib/apiclient/contrib/buzz/future.json -> build/bdist.macosx-10.6-i386/egg/apiclient/contrib/buzz creating build/bdist.macosx-10.6-i386/egg/apiclient/contrib/latitude copying build/lib/apiclient/contrib/latitude/future.json -> build/bdist.macosx-10.6-i386/egg/apiclient/contrib/latitude creating build/bdist.macosx-10.6-i386/egg/apiclient/contrib/moderator copying build/lib/apiclient/contrib/moderator/future.json -> build/bdist.macosx-10.6-i386/egg/apiclient/contrib/moderator copying build/lib/apiclient/discovery.py -> build/bdist.macosx-10.6-i386/egg/apiclient copying build/lib/apiclient/errors.py -> build/bdist.macosx-10.6-i386/egg/apiclient creating build/bdist.macosx-10.6-i386/egg/apiclient/ext copying build/lib/apiclient/ext/__init__.py -> build/bdist.macosx-10.6-i386/egg/apiclient/ext copying build/lib/apiclient/ext/appengine.py -> build/bdist.macosx-10.6-i386/egg/apiclient/ext copying build/lib/apiclient/ext/authtools.py -> build/bdist.macosx-10.6-i386/egg/apiclient/ext copying build/lib/apiclient/ext/django_orm.py -> build/bdist.macosx-10.6-i386/egg/apiclient/ext copying build/lib/apiclient/http.py -> build/bdist.macosx-10.6-i386/egg/apiclient copying build/lib/apiclient/model.py -> build/bdist.macosx-10.6-i386/egg/apiclient copying build/lib/apiclient/oauth.py -> build/bdist.macosx-10.6-i386/egg/apiclient creating build/bdist.macosx-10.6-i386/egg/uritemplate copying build/lib/uritemplate/__init__.py -> build/bdist.macosx-10.6-i386/egg/uritemplate byte-compiling build/bdist.macosx-10.6-i386/egg/apiclient/__init__.py to __init__.pyc byte-compiling build/bdist.macosx-10.6-i386/egg/apiclient/anyjson.py to anyjson.pyc byte-compiling build/bdist.macosx-10.6-i386/egg/apiclient/discovery.py to discovery.pyc byte-compiling build/bdist.macosx-10.6-i386/egg/apiclient/errors.py to errors.pyc byte-compiling build/bdist.macosx-10.6-i386/egg/apiclient/ext/__init__.py to __init__.pyc byte-compiling build/bdist.macosx-10.6-i386/egg/apiclient/ext/appengine.py to appengine.pyc byte-compiling build/bdist.macosx-10.6-i386/egg/apiclient/ext/authtools.py to authtools.pyc byte-compiling build/bdist.macosx-10.6-i386/egg/apiclient/ext/django_orm.py to django_orm.pyc byte-compiling build/bdist.macosx-10.6-i386/egg/apiclient/http.py to http.pyc byte-compiling build/bdist.macosx-10.6-i386/egg/apiclient/model.py to model.pyc byte-compiling build/bdist.macosx-10.6-i386/egg/apiclient/oauth.py to oauth.pyc byte-compiling build/bdist.macosx-10.6-i386/egg/uritemplate/__init__.py to __init__.pyc creating build/bdist.macosx-10.6-i386/egg/EGG-INFO copying google_api_python_client.egg-info/PKG-INFO -> build/bdist.macosx-10.6-i386/egg/EGG-INFO copying google_api_python_client.egg-info/SOURCES.txt -> build/bdist.macosx-10.6-i386/egg/EGG-INFO copying google_api_python_client.egg-info/dependency_links.txt -> build/bdist.macosx-10.6-i386/egg/EGG-INFO copying google_api_python_client.egg-info/top_level.txt -> build/bdist.macosx-10.6-i386/egg/EGG-INFO zip_safe flag not set; analyzing archive contents... apiclient.discovery: module references __file__ creating dist creating 'dist/google_api_python_client-0.1-py2.4.egg' and adding 'build/bdist.macosx-10.6-i386/egg' to it removing 'build/bdist.macosx-10.6-i386/egg' (and everything under it) Processing google_api_python_client-0.1-py2.4.egg creating /Users/strefethen/Library/Python2.4/site-packages/google_api_python_client-0.1-py2.4.egg Extracting google_api_python_client-0.1-py2.4.egg to /Users/strefethen/Library/Python2.4/site-packages Adding google-api-python-client 0.1 to easy-install.pth file Installed /Users/strefethen/Library/Python2.4/site-packages/google_api_python_client-0.1-py2.4.egg Processing dependencies for google-api-python-client==0.1 Finished processing dependencies for google-api-python-client==0.1 Setup complete!
Finally, attempt to run the Buzz sample which caused the following error
SteveT:buzz strefethen$ python three_legged_dance.py Go to the following link in your browser: https://www.google.com/buzz/api/auth/OAuthAuthorizeToken?scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fbuzz&domain=anonymous&oauth_token=4%2FetZ5lubFdHfPmrqf0pg9IRR_Nury ^CTraceback (most recent call last): File "three_legged_dance.py", line 40, in ? run(flow, 'buzz.dat') File "/Users/strefethen/Library/Python2.4/site-packages/google_api_python_client-0.1-py2.4.egg/apiclient/ext/authtools.py", line 121, in run httpd.handle_request() File "/opt/local/lib/python2.4/SocketServer.py", line 217, in handle_request request, client_address = self.get_request() File "/opt/local/lib/python2.4/SocketServer.py", line 373, in get_request return self.socket.accept() File "/opt/local/lib/python2.4/socket.py", line 161, in accept sock, addr = self._sock.accept():
I hadn’t reviewed the code (yeah, not necessarily the brightest idea but hey, it’s Google right?). The above error occurred because I had an application running on port 8080 and didn’t realize the demo was going to require that. After shutting down Hudson I was able to authenticate and move forward.
SteveT:buzz strefethen$ python three_legged_dance.py Go to the following link in your browser: https://www.google.com/buzz/api/auth/OAuthAuthorizeToken?scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fbuzz&domain=anonymous&oauth_token=4%2FyDtHZJcU8xD_XP023fUiaKC93wyE You have successfully authenticated.
However, I ran into another problem which is where the significance of python 2.4 comes in. Attempting to run the buzz.py example I got the following error:
SteveT:buzz strefethen$ python buzz.py Traceback (most recent call last): File "buzz.py", line 75, in ? main() File "buzz.py", line 37, in main activitylist = activities.list( File "/Users/strefethen/Library/Python2.4/site-packages/google_api_python_client-0.1-py2.4.egg/apiclient/discovery.py", line 243, in method new_base_url = url_result.scheme + '://' + url_result.netloc AttributeError: 'tuple' object has no attribute 'scheme'
After a few minutes of tangling with Google I found this page which gave me a clue. Specifically, it was dag’s post from 2008/12/9 relating to urlparse and a difference between python 2.4 and 2.5. I opened the above discovery.py file and searched for ‘scheme’ in order to change the reference to something that would work in 2.4. I had to repeat this for ‘netloc’ and ‘path’ with url_result, ,  respectively. After saving the file the sample worked as expected.
Granted I’ve probably included a lot more information with respect to the console output above but there are are few things I’m interested in keeping so this is a great place to do just that.
Now, time to go off and have some fun with these Google API’s.
I’m particularly interested in the Moderator API and I’m curious if anyone has written apps to completely replace the Google Moderator UI with a custom design?