烧瓶 - 标题不转换为Unicode? [英] Flask - headers are not converted to unicode?

查看:182
本文介绍了烧瓶 - 标题不转换为Unicode?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述




  • 烧瓶(v。0.8)

  • storm ORM(v。0.19)

  • Apache与mod_wsgi



一个自定义的HTTP标头, Unison-UUID 我在某些时候用来检索我的数据库中的信息。




$ b $ pre $ uuid = flask.request.headers [这是简单的稍微重写的代码片段] 'Unison -UUID']
store = storm.locals.Store(my_database)
user = store.get(models.User,uuid)
$ b $ User 类或多或少是这样的:

  class User(Storm):
uuid = Unicode(primary = True)
#其他列....


 文件/Users/lum/Documents/unison-recsys/www/api/unison/unison.py,第27行,装饰
user = g.store.get(models.User,uuid)
文件/Users/lum/Documents/unison-recsys/venv/lib/python2.6/site-packages/storm/store.py,第165行,获取
variable = column.variable_factory(value = variable)
文件/Users/lum/Documents/unison-recsys/venv/lib/python2.6/site-packages/storm/变量.py,第396行,在parse_set
%(type(value),value))
TypeError:预期unicode,找到< type'str'>:'00000000-0000-0000- 0000-000000000009'

我不明白为什么会发生这种情况,我可以做些什么。我以为 Flask是100%unicode



我发现的一个快速解决方案是解码标头值,即 uuid = uuid.decode('utf-8')。这真的是需要做的吗?这似乎有点hackish。有没有办法直接得到unicode,而不必手动解码它? 解决方案

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


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

单词请求链接到 http://werkzeug.pocoo.org/docs/wrappers/#werkzeug.wrappers。请求阅读


Request Response 类的子类 BaseRequest
BaseResponse mixins Werkzeug提供:

BaseRequest 指向 http://werkzeug.pocoo。 org / docs / wrappers /#werkzeug.wrappers.BaseRequest 在哪里阅读


标题

来自WSGI environ的头文件不可变 EnvironHeaders


$ c> EnvironHeaders 链接到 http:// werkzeug.pocoo.org/docs/datastructures/#werkzeug.datastructures.EnvironHeaders 我们阅读的地方


这提供了相同的界面作为标题,并且是从WSGI环境构建的。 是...不,它没有链接,但应该链接到 http://werkzeug.pocoo.org/docs/datastructures/#werkzeug.datastructures.Headers 我们在哪里阅读


头文件大部分与Python兼容 wsgiref.headers.Headers class


其中短语 wsgiref.headers.Headers 链接到 http://docs.python.org/dev/library/wsgiref.html#wsgiref.headers.Headers 我们在哪里阅读



lockquote
创建一个类似映射的对象包装头,它必须是
头名称/值元组的列表,如 PEP 3333


短语 PEP 3333 指向 http://www.python.org/dev/peps/pep- 3333 / 没有明确定义什么类型的标题应该b e,但是在搜索word headers 之后,我们发现这个语句

lockquote

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

pre $ Native字符串(总是使用名为str的类型实现)
用于请求/响应头文件和元数据
Bytestrings(在Python 3中使用`bytes`类型实现,
和`str`在别处实现),用于请求主体和
响应(例如, POST / PUT输入数据和HTML页面输出)。


这就是为什么在Python 2中, c> str 不是 unicode

现在让我们转到解码。


$ b 您的 .decode('utf-8')和mensi的 .decode('ascii' )(也不要盲目期待任何其他编码)是普遍的好,因为在理论上,HTTP头字段值可以传输任何东西;棘手的部分是让所有各方(发送者,接收者和中间者)就编码达成一致。话虽如此,我认为你应该按照朱利安Reshke的建议

< blockquote>

因此,安全的做法是坚持使用ASCII码,然后在
上面选择一个编码,例如RFC 5987中定义的编码。 b
$ b $ p

在检查您所支持的用户代理(浏览器)已经实现了它之后。

超文本传输​​协议(HTTP)标题字段参数的字符集和语言编码是一种用于超文本传输​​协议(HTTP)的字符集和语言编码


I'm developping a small web service in python using:

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

I have a custom HTTP header, Unison-UUID which I'm using at some point to retrieve information in my database.

here's the (slightly rewritten for simplicity) snippet that I'm having trouble with:

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

The class User is more or less like this:

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

The code above fails in the following way:

  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'

I don't really understand why this is happening and what I can do about it. I thought Flask was 100% unicode.

A quick fix I found is to decode the header value, i.e uuid = uuid.decode('utf-8'). Is this really what needs to be done? This seems a bit hackish. Is there no way to get unicode directly, without having to "decode" it manually?

解决方案

At http://flask.pocoo.org/docs/api/#flask.request we read

The request object is an instance of a Request subclass and provides all of the attributes Werkzeug defines.

The word Request links to http://werkzeug.pocoo.org/docs/wrappers/#werkzeug.wrappers.Request where we read

The Request and Response classes subclass the BaseRequest and BaseResponse classes and implement all the mixins Werkzeug provides:

The word BaseRequest links to http://werkzeug.pocoo.org/docs/wrappers/#werkzeug.wrappers.BaseRequest where we read

headers
The headers from the WSGI environ as immutable EnvironHeaders.

The word EnvironHeaders links to http://werkzeug.pocoo.org/docs/datastructures/#werkzeug.datastructures.EnvironHeaders where we read

This provides the same interface as Headers and is constructed from a WSGI environment.

The word Headers is... no, it's not linked but it should has been linked to http://werkzeug.pocoo.org/docs/datastructures/#werkzeug.datastructures.Headers where we read

Headers is mostly compatible with the Python wsgiref.headers.Headers class

where the phrase wsgiref.headers.Headers links to http://docs.python.org/dev/library/wsgiref.html#wsgiref.headers.Headers where we read

Create a mapping-like object wrapping headers, which must be a list of header name/value tuples as described in PEP 3333.

The phrase PEP 3333 links to http://www.python.org/dev/peps/pep-3333/ where there's no explicit definition of what type headers should be but after searching for word headers for a while we find this statement

WSGI therefore defines two kinds of "string":

"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).

That's why in Python 2 you get headers as str not unicode.

Now let's move to decoding.

Neither your .decode('utf-8') nor mensi's .decode('ascii') (nor blindly expecting any other encoding) is universally good because 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.. Having said that I think you should act according to Julian Reshke's advice

Thus, the safe way to do this is to stick to ASCII, and choose an encoding on top of that, such as the one defined in RFC 5987.

after checking that User Agents (browsers) you support have implemented it.

Title of RFC 5987 is Character Set and Language Encoding for Hypertext Transfer Protocol (HTTP) Header Field Parameters

这篇关于烧瓶 - 标题不转换为Unicode?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆