使用 Flask 和 Python 3 测试文件上传

Posted

技术标签:

【中文标题】使用 Flask 和 Python 3 测试文件上传【英文标题】:Testing file upload with Flask and Python 3 【发布时间】:2013-12-03 12:17:15 【问题描述】:

我将 Flask 与 Python 3.3 一起使用,我知道支持仍处于试验阶段,但在尝试测试文件上传时遇到了错误。我正在使用 unittest.TestCase 并基于我在我正在尝试的文档中看到的 Python 2.7 示例

rv = self.app.post('/add', data=dict(
                               file=(io.StringIO("this is a test"), 'test.pdf'),
                           ), follow_redirects=True)

得到

TypeError: 'str' does not support the buffer interface

我尝试了一些关于 io.StringIO 的变体,但找不到任何可行的方法。非常感谢任何帮助!

完整的堆栈跟踪是

Traceback (most recent call last):
  File "archive_tests.py", line 44, in test_add_transcript
    ), follow_redirects=True)
  File "/srv/transcript_archive/py3env/lib/python3.3/site-packages/werkzeug/test.py", line 771, in post
    return self.open(*args, **kw)
  File "/srv/transcript_archive/py3env/lib/python3.3/site-packages/flask/testing.py", line 108, in open
    follow_redirects=follow_redirects)
  File "/srv/transcript_archive/py3env/lib/python3.3/site-packages/werkzeug/test.py", line 725, in open
    environ = args[0].get_environ()
  File "/srv/transcript_archive/py3env/lib/python3.3/site-packages/werkzeug/test.py", line 535, in get_environ
    stream_encode_multipart(values, charset=self.charset)
  File "/srv/transcript_archive/py3env/lib/python3.3/site-packages/werkzeug/test.py", line 98, in stream_encode_multipart
    write_binary(chunk)
  File "/srv/transcript_archive/py3env/lib/python3.3/site-packages/werkzeug/test.py", line 59, in write_binary
    stream.write(string)
TypeError: 'str' does not support the buffer interface

【问题讨论】:

什么是完整的回溯?为什么要用io.StringIO() 发帖,难道这里需要二进制文件对象?例如,io.BytesIO(b'this is a test') 可能会起作用。 查看werkzeug FileStorage object(在测试中处理文件上传)我看不到任何可以提供足够信息的东西。您需要添加完整回溯,以便任何人都能说出任何有用的话。 抱歉,添加了跟踪。我使用io.String,因为werkzeug 示例在他们的示例link 中使用StringIO。使用io.BytesIO 没有区别。 StringIO 在 Python 2 中处理 字节字符串,而不是 Unicode。 Python 3 的等价物是 io.BytesIO 好的,file=(io.BytesIO(b"this is a test"), 'test.pdf') 确实有效,我在您最初回复后进行测试时忘记将b 放在引用的文本前面。谢谢! 【参考方案1】:

在 Python 3 中,您需要使用 io.BytesIO()(带有字节值)来模拟上传的文件:

rv = self.app.post('/add', data=dict(
                               file=(io.BytesIO(b"this is a test"), 'test.pdf'),
                           ), follow_redirects=True)

注意定义 bytes 文字的 b'...' 字符串。

在 Python 2 测试示例中,StringIO() 对象包含一个字节字符串,而不是 unicode 值,而在 Python 3 中,io.BytesIO() 是等价的。

【讨论】:

如果您使用的是实际文件而不是 BytesIO,请记住使用open('filename.data', 'rb')以二进制模式打开它

以上是关于使用 Flask 和 Python 3 测试文件上传的主要内容,如果未能解决你的问题,请参考以下文章

利用python的flask框架开发智能合约

nginx+uwsgi+flask搭建后怎么访问.py文件

python自动化自动化测试平台开发:2.flask技术讲解上

Python flask虚拟环境安装

Python 基于Flask的Web开发用户登录 注册

是否可以在 Flask 和 Python 3 中使用 websockets?