Pyramid on App Engine gets "InvalidResponseError: header values must be str, got 'unicode'

|▌冷眼眸甩不掉的悲伤 提交于 2019-12-23 13:32:28

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!