我正在使用GAE将webapp迁移到python 2.7,并显示以下错误消息:
File "/base/python27_runtime/python27_lib/versions/1/google/appengine/runtime/wsgi.py", line 129, in _StartResponse raise InvalidResponseError('headers must be str') InvalidResponseError: headers must be str
这是什么意思?我看到了someone else had the same problem,但我的情况不同。我的渲染方法是否有来自basehandler类的东西?
我的代码:
class BaseHandler(webapp.RequestHandler):
facebook = None
user = None
csrf_protect = True
@property
def current_user(self):
if not hasattr(self, "_current_user"):
self._current_user = None
cookie = facebook.get_user_from_cookie(
self.request.cookies, conf.FACEBOOK_APP_ID, conf.FACEBOOK_APP_SECRET)
logging.debug("logging cookie"+str(cookie))
if cookie:
# Store a local instance of the user data so we don't need
# a round-trip to Facebook on every request
user = FBUser.get_by_key_name(cookie["uid"])
logging.debug("user "+str(user))
logging.debug("username "+str(user.name))
if not user:
graph = facebook.GraphAPI(cookie["access_token"])
profile = graph.get_object("me")
user = User(key_name=str(profile["id"]),
user_id=str(profile["id"]),
name=profile["name"],
profile_url=profile["link"],
access_token=cookie["access_token"])
user.put()
elif user.access_token != cookie["access_token"]:
user.access_token = cookie["access_token"]
user.put()
self._current_user = user
return self._current_user
def initialize(self, request, response):
super(BaseHandler, self).initialize(request, response)
try:
self.init_facebook()
self.init_csrf()
self.response.headers[u'P3P'] = u'CP=HONK' # iframe cookies in IE
except Exception, ex:
self.log_exception(ex)
raise
def handle_exception(self, ex, debug_mode):
self.log_exception(ex)
self.render(u'error', trace=traceback.format_exc(),
debug_mode=debug_mode)
def log_exception(self, ex):
msg = (str(ex) or ex.__class__.__name__) + u': \n' \
+ traceback.format_exc()
if isinstance(ex, urlfetch.DownloadError) or isinstance(ex,
DeadlineExceededError) or isinstance(ex, CsrfException) \
or isinstance(ex, taskqueue.TransientError):
logging.warn(msg)
else:
logging.error(msg)
def set_cookie(
self,
name,
value,
expires=None,
):
if value is None:
value = 'deleted'
expires = datetime.timedelta(minutes=-50000)
jar = Cookie.SimpleCookie()
jar[name] = value
jar[name]['path'] = u'/'
if expires:
if isinstance(expires, datetime.timedelta):
expires = datetime.datetime.now() + expires
if isinstance(expires, datetime.datetime):
expires = expires.strftime('%a, %d %b %Y %H:%M:%S')
jar[name]['expires'] = expires
self.response.headers.add_header(*jar.output().split(u': ', 1))
def render(self, name, **data):
if not data:
data = {}
data[u'js_conf'] = json.dumps({u'appId': conf.FACEBOOK_APP_ID,
u'canvasName': conf.FACEBOOK_CANVAS_NAME,
u'userIdOnServer'
: (self.user.user_id if self.user else None)})
data[u'logged_in_user'] = self.user
data[u'message'] = self.get_message()
data[u'csrf_token'] = self.csrf_token
data[u'canvas_name'] = conf.FACEBOOK_CANVAS_NAME
self.response.out.write(template.render(os.path.join(os.path.dirname(__file__),
'templates', name + '.html'), str(data)))
def init_facebook(self):
facebook = Facebook()
user = None
# initial facebook request comes in as a POST with a signed_request
if u'signed_request' in self.request.POST:
facebook.load_signed_request(self.request.get('signed_request'
))
# we reset the method to GET because a request from facebook with a
# signed_request uses POST for security reasons, despite it
# actually being a GET. in webapp causes loss of request.POST data.
self.request.method = u'GET'
self.set_cookie('u', facebook.user_cookie,
datetime.timedelta(minutes=1440))
elif 'u' in self.request.cookies:
facebook.load_signed_request(self.request.cookies.get('u'))
# try to load or create a user object
if facebook.user_id:
user = User.get_by_key_name(facebook.user_id)
if user:
# update stored access_token
if facebook.access_token and facebook.access_token \
!= user.access_token:
user.access_token = facebook.access_token
user.put()
# refresh data if we failed in doing so after a realtime ping
if user.dirty:
user.refresh_data()
# restore stored access_token if necessary
if not facebook.access_token:
facebook.access_token = user.access_token
if not user and facebook.access_token:
me = facebook.api(u'/me', {u'fields': _USER_FIELDS})
try:
friends = [user[u'id'] for user in me[u'friends'
][u'data']]
user = User(
key_name=facebook.user_id,
user_id=facebook.user_id,
friends=friends,
access_token=facebook.access_token,
name=me[u'name'],
email=me.get(u'email'),
picture=me[u'picture'],
)
user.put()
except KeyError, ex:
pass # ignore if can't get the minimum fields
self.facebook = facebook
self.user = user
def init_csrf(self):
self.csrf_token = self.request.cookies.get(u'c')
if not self.csrf_token:
self.csrf_token = str(uuid4())[:8]
self.set_cookie('c', self.csrf_token)
if self.request.method == u'POST' and self.csrf_protect \
and self.csrf_token != self.request.POST.get(u'_csrf_token'
):
raise CsrfException(u'Missing or invalid CSRF token.')
def set_message(self, **obj):
self.set_cookie('m',
(base64.b64encode(json.dumps(obj)) if obj else None))
def get_message(self):
message = self.request.cookies.get(u'm')
if message:
self.set_message() # clear the current cookie
return json.loads(base64.b64decode(message))
import random
from google.appengine.api import files, images
class CyberFazeHandler(BaseHandler):
"""Handle the home page that renders 3 random images"""
def get_random_image(self, category):
"""get a random image O(1) by category"""
q = FileInfo.all()
q.filter('category =', category)
q.filter('randomvalue >=', random.random())
return q.get()
def get(self):
logging.info('get ')
"""build up the random face from the random body """
try:
eyes_image = self.get_random_image(category='eyes')
nose_image = self.get_random_image(category='nose')
mouth_image = self.get_random_image(category='mouth')
logging.info('set mouth id '+str(eyes_image.blob.key()))
eyes_data = blobstore.fetch_data(eyes_image.blob.key(), 0, 50000)
eyes_img = images.Image(image_data=eyes_dat
nose_data = blobstore.fetch_data(nose_image.blob.key(), 0, 50000)
nose_img = images.Image(image_data=nose_data)
logging.info('eyes image ')
mouth_data = blobstore.fetch_data(mouth_image.blob.key(),0, 50000)
mouth_img = images.Image(image_data=mouth_data)
minimum = int(min(eyes_img.width, nose_img.width, mouth_img.width))
eyes_url = images.get_serving_url(str(eyes_image.blob.key()), size=minimum)
nose_url = images.get_serving_url(str(nose_image.blob.key()), size=minimum)
mouth_url = images.get_serving_url(str(mouth_image.blob.key()), size=minimum)
self.render('cyberfaze', minimum=minimum, eyes_image=eyes_image, eyes_url=eyes_url, nose_image=nose_image, nose_url=nose_url, mouth_image=mouth_image, mouth_url=mouth_url, form_url=blobstore.create_upload_url('/upload'),)
答案 0 :(得分:3)
self.response.headers[u'P3P'] = u'CP=HONK'
尝试在此处传递字符串,而不是转换为unicode。