Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Testing file upload with Flask and Python 3

I'm using Flask with Python 3.3 and I know support is still experimental but I'm running into errors when trying to test file uploads. I'm using unittest.TestCase and based on Python 2.7 examples I've seen in the docs I'm trying

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

and getting

TypeError: 'str' does not support the buffer interface

I've tried a few variations around io.StringIO but can't find anything that works. Any help is much appreciated!

The full stack trace is

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
like image 799
steverippl Avatar asked Nov 19 '13 19:11

steverippl


1 Answers

In Python 3, you need to use io.BytesIO() (with a bytes value) to simulate an uploaded file:

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

Note the b'...' string defining a bytes literal.

In the Python 2 test examples, the StringIO() object holds a byte string, not a unicode value, and in Python 3, io.BytesIO() is the equivalent.

like image 104
Martijn Pieters Avatar answered Nov 03 '22 05:11

Martijn Pieters