Friday, September 26, 2008

GData and DJango's HttpResponse Clashing -- 'unicode' object has no attribute 'content'

GAE's GData API appears to be going through some rapid flux and our app is taking its punches. The changes are exposing some deeper issues which we've just tackled. Here's a doozy:

views.py
from django.http import HttpResponse
from myapp.models import *
...
  return HttpResponse("...")

models.py
from gdata.alt.appengine import *  # For new GData API calls
...

The above code listing illustrates our approach to patching the new GData APIs into our model calls. We didn't realize that we were also introducing the error below. Why? Because HttpResponse is defined in both django.http AND gdata.alt.appengine. This causes import-line-ordering-sensitivities.

The solution—even for a newbie python coder—is easy. You can reorder imports in the view to make sure the LAST imported namespace is the one you want. You can restrict the import to gdata.alt.* and then reference appengine.HttpResponse, etc as needed.

This error text is particular unhelpful and the error path unrelated to the root cause. Hopefully this will match others hitting the same problem.

AttributeError at /l/agpyaWdod...RgCDA/widget.js
'unicode' object has no attribute 'content'
Request Method: GET
Request URL: http://l.../l/agpyaW...CDA/widget.js
Exception Type: AttributeError
Exception Value: 
'unicode' object has no attribute 'content'
Exception Location: /.../gdata/alt/appengine.py in __init__, line 145
Python Executable: /System/Library/Frameworks/Python.framework/Versions/2.5/Resources/Python.app/Contents/MacOS/Python
Python Version: 2.5.1
Python Path: ['/.../rightreply', '/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine', '/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/django', '/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webob', '/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/yaml/lib', '/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine', '/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources', '/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python25.zip', '/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5', '/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/plat-darwin', '/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/plat-mac', '/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/plat-mac/lib-scriptpackages', '/System/Library/Frameworks/Python.framework/Versions/2.5/Extras/lib/python', '/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/lib-tk', '/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/lib-dynload', '/Library/Python/2.5/site-packages', '/System/Library/Frameworks/Python.framework/Versions/2.5/Extras/lib/python/PyObjC']
Server time: Thu, 25 Sep 2008 19:42:39 +0000

Note: This also had variants with the error of "'str' object has no attribute 'content'."

2 comments:

Jeff Scudder said...

This is why several Python style guides state that * imports should never be used ;)

For example: http://code.google.com/p/soc/wiki/PythonStyleGuide#Module_and_package_imports

# Module and package imports: Yes, except for wildcard imports

Jonathan Siegel said...

Thanks Jeff! This is a great style guide reference. Appreciate the pointer.