问题
I am using Pyramid 1.3 with the AppEngine 1.6.4 SDK on OS X 10.7.3. I am using Python 2.7 and have threadsafe true in app.yaml.
@view_config(route_name='manager_swms', permission='manager', renderer='manager/swms.jinja2')
def manager_swms(request):
"""Generates blobstore url and passes users swms in swms table"""
# generate url for any form upload that may occur
upload_url = blobstore.create_upload_url('/upload_swm')
user = get_current_user(request)
swms = DBSession.query(SWMS).filter_by(owner_id=int(user.id)).all()
return {
"analytics_id": analytics_id,
"user": get_current_user(request),
"upload_url": upload_url,
"swms": [(x.filename, x.blob_key) for x in swms]
}
class BlobstoreUploadHandler(object):
"""Base class for creation blob upload handlers."""
def __init__(self, *args, **kwargs):
self.__uploads = None
def get_uploads(self, field_name=None):
"""Get uploads sent to this handler.
Args:
field_name: Only select uploads that were sent as a specific field.
Returns:
A list of BlobInfo records corresponding to each upload.
Empty list if there are no blob-info records for field_name.
"""
if self.__uploads is None:
self.__uploads = {}
for key, value in self.request.params.items():
if isinstance(value, cgi.FieldStorage):
if 'blob-key' in value.type_options:
self.__uploads.setdefault(key, []).append(
blobstore.parse_blob_info(value))
if field_name:
try:
return list(self.__uploads[field_name])
except KeyError:
return []
else:
results = []
for uploads in self.__uploads.itervalues():
results += uploads
return results
@view_config(route_name='upload_swm', permission='manager')
class UploadHandler(BlobstoreUploadHandler):
''' Handles redirects from Blobstore uploads. '''
def __init__(self, request):
self.request = request
super(UploadHandler, self).__init__()
def __call__(self):
user = get_current_user(self.request)
for blob_info in self.get_uploads('file'):
new_swm = SWMS(
owner_id = int(user.id),
blob_key = str(blob_info.key()),
filename = blob_info.filename,
size = blob_info.size,
)
DBSession.add(new_swm)
DBSession.flush()
# redirect to swms page
return HTTPFound(location='/manager/swms')
In the above code, manager_swms() generates a page which includes a form for uploading a file into the Blobstore. The form works OK and I can see the blob appear in the Blobstore when the form is used. The redirect from the blobstore POST is then to /upload_swm where I successfully take BlobInfo details and place them into a SQL table. All of this is good and the final thing I want to do is redirect to the first page so another file can be uploaded if need be and I can show the list of files uploaded.
As per Pyramid documentation, I am using HTTPFound(location='/manager/swms') [the original page URL] to try and redirect however I get:
ERROR 2012-03-29 22:56:38,170 wsgi.py:208]
Traceback (most recent call last):
File "/Users/tim/work/OHSPro/var/parts/google_appengine/google/appengine/runtime/wsgi.py", line 196, in Handle
result = handler(self._environ, self._StartResponse)
File "lib/dist/pyramid/router.py", line 195, in __call__
foo = response(request.environ, start_response)
File "lib/dist/pyramid/httpexceptions.py", line 291, in __call__
foo = Response.__call__(self, environ, start_response)
File "lib/dist/webob/response.py", line 922, in __call__
start_response(self.status, headerlist)
File "/Users/tim/work/OHSPro/var/parts/google_appengine/google/appengine/runtime/wsgi.py", line 150, in _StartResponse
_GetTypeName(header[1]))
InvalidResponseError: header values must be str, got 'unicode'
INFO 2012-03-29 22:56:38,174 dev_appserver_blobstore.py:408] Upload handler returned 500
INFO 2012-03-29 22:56:38,193 dev_appserver.py:2884] "POST /_ah/upload/ahJkZXZ-cHJvdG8tc2NvaHNwcm9yGwsSFV9fQmxvYlVwbG9hZFNlc3Npb25fXxgTDA HTTP/1.1" 500 -
AppEngine is clearly objecting to unicode in the HTTP header but I'm not doing anything unusual AFAIK. If I drop into pdb and take a look at the HTTPFound object, the headers are:
ResponseHeaders([('Content-Type', 'text/html; charset=UTF-8'), ('Content-Length', '0'), ('Location', '/manager/swms')])
Why would I get a unicode problem from these?
回答1:
so it looks like you are overriding appengine's supported webob which is 1.1.1 on the 2.7 runtime. And pyramid 1.3 depends on webob>=1.2. This is most likely the problem because it was the Blobstore handler stuff that was keeping the sdk held back at webob==0.9 until SDK 1.6.4 was released.
FWIW, this problem is expected to be resolved by SDK 1.6.5 (late April). The only reason I know this is because I was trying to get all this crap resolved when the 2.7 runtime was deemed ready for general use, yet the SDK didn't support it. see this issue for more details.
If possible, I would suggest running it with pyramid 1.2, I know that works fine on appengine. And Just hold off on moving to 1.3 for a few weeks. :)
回答2:
Yet another answer... adding a str() fixes the problem, but not the root cause. I spent hours trying to figure out why one particular redirect raised this error while others didn't, before noticing that the URL for the bad redirect was missing the initial "/".
I have no idea why this is the case - possibly an incomplete path is processed differently from a complete one. But if you hit this error try changing:
self.redirect('home.view')
to:
self.redirect('/home.view')
来源:https://stackoverflow.com/questions/9934923/pyramid-on-app-engine-gets-invalidresponseerror-header-values-must-be-str-got