Flask - 标题未转换为unicode?

时间:2012-04-12 13:40:29

标签: python unicode flask werkzeug storm-orm

我正在使用以下方法在python中开发一个小型Web服务:

  • Flask(v.8.8)
  • storm ORM(v。0.19)
  • Apache with mod_wsgi

我有一个自定义HTTP标头,Unison-UUID我正在使用它来检索我的数据库中的信息。

这是(稍为简单的重写)片段,我遇到了麻烦:

uuid = flask.request.headers['Unison-UUID']
store = storm.locals.Store(my_database)
user = store.get(models.User, uuid)

班级User或多或少是这样的:

class User(Storm):
    uuid = Unicode(primary=True)
    # Other columns....

上述代码以下列方式失败:

  File "/Users/lum/Documents/unison-recsys/www/api/unison/unison.py", line 27, in decorated
    user = g.store.get(models.User, uuid)
  File "/Users/lum/Documents/unison-recsys/venv/lib/python2.6/site-packages/storm/store.py", line 165, in get
    variable = column.variable_factory(value=variable)
  File "/Users/lum/Documents/unison-recsys/venv/lib/python2.6/site-packages/storm/variables.py", line 396, in parse_set
    % (type(value), value))
TypeError: Expected unicode, found <type 'str'>: '00000000-0000-0000-0000-000000000009'

我真的不明白为什么会这样,我能做些什么呢。我想Flask was 100% unicode

我发现快速解决方法是解码标头值,即uuid = uuid.decode('utf-8')。这真的需要做什么?这看起来有点骇人听闻。有没有办法直接获得unicode,而不必手动“解码”它?

2 个答案:

答案 0 :(得分:13)

我们在http://flask.pocoo.org/docs/api/#flask.request阅读了

  

请求对象是Request子类的实例并提供   Werkzeug定义的所有属性。

单词Request链接到我们阅读的http://werkzeug.pocoo.org/docs/wrappers/#werkzeug.wrappers.Request

  

RequestResponse类是BaseRequest和。{   BaseResponse类和实现Werkzeug提供的所有mixins:

单词BaseRequest链接到我们阅读的http://werkzeug.pocoo.org/docs/wrappers/#werkzeug.wrappers.BaseRequest

  


   WSGI环境中的标头为不可变EnvironHeaders

单词EnvironHeaders链接到我们阅读的http://werkzeug.pocoo.org/docs/datastructures/#werkzeug.datastructures.EnvironHeaders

  

这提供了与 Headers 相同的接口,并且是从WSGI环境构建的。

Headers 这个词是......不,它没有链接但它应该链接到我们阅读的http://werkzeug.pocoo.org/docs/datastructures/#werkzeug.datastructures.Headers

  

标题主要与Python wsgiref.headers.Headers

兼容

短语wsgiref.headers.Headers链接到我们阅读的http://docs.python.org/dev/library/wsgiref.html#wsgiref.headers.Headers

  

创建一个类似于映射的对象包装头,它必须是一个列表   标题名称/值元组,如PEP 3333中所述。

短语PEP 3333链接到http://www.python.org/dev/peps/pep-3333/,其中没有明确定义标题应该是什么类型但在搜索单词标题一段时间后我们发现此声明

  因此,WSGI定义了两种“字符串”:

"Native" strings (which are always implemented using the type named str)
that are used for request/response headers and metadata
"Bytestrings" (which are implemented using the `bytes` type in Python 3,
and `str` elsewhere), that are used for the bodies of requests and
responses (e.g. POST/PUT input data and HTML page outputs).

这就是为什么在Python 2中,标题为str而不是unicode

现在让我们转向解码。

.decode('utf-8')和男性.decode('ascii')(也不是盲目地期待任何其他编码)都不是普遍好的,因为In theory, HTTP header field values can transport anything; the tricky part is to get all parties (sender, receiver, and intermediates) to agree on the encoding.。话虽如此,我认为你应该按照Julian Reshke的advice

行事
  

因此,安全的方法是坚持使用ASCII,并在顶部选择编码   其中,例如RFC 5987中定义的那个。

检查您支持的用户代理(浏览器)是否已实现它。

RFC 5987的标题是超文本传输​​协议(HTTP)标头字段参数的字符集和语言编码

答案 1 :(得分:0)

标题值为ASCII,请参阅Acorn的链接问题。

你可以在这里做的是手动解码(尽管你应该使用uuid.decode('ascii')而不是utf-8)或将你的字段更改为RawStr而不是Unicode