Client: FormData._gen_form_data ignores filename, explodes #2201
Description
I am using the client to upload a file using FormData, almost exactly the same code as shown in this example. The main difference is that I am passing a file created by tempfile.TemporaryFile as the second argument to add_field.
The result is: TypeError: Can not serialize value type: <class '_io.BufferedRandom'> headers: {'Content-Type': 'application/vnd.ms-excel'} value: <_io.BufferedRandom name=23>
The root exception is actually thrown from helpers.guess_filename: TypeError: 'int' object is not subscriptable
Expected behaviour
There should be no need to call guess_filename because I specified a filename:
form.add_field('file', data, filename=filename, content_type=content_type)
And even if I didn't provide a filename, guess_filename should not throw an exception if name is not a string (which is apparently the case for tempfiles; notice that my tempfile has the number 23 for a name).
Actual behaviour
FormData._gen_form_data is not passing the filename to payload.get_payload, even though the filename is available. It seems like the code could be changed to include filename=dispparams.get('filename') in the kwargs for get_payload.
guess_filename assumes that name will be a string. Oddly enough, sometimes it's a number.
Steps to reproduce
Here is my code that produces the error. data is a tempfile.TemporaryFile(). The exception is thrown from the post call. url, filename, and content_type are all valid strings.
async def post_temp_file(self, url, filename, content_type, data):
form = FormData()
form.add_field('file', data, filename=filename, content_type=content_type)
async with self.rest.post(url, data=form) as response:
await self._raise_for_status(response)
body = await response.text()
return json.loads(body)Workaround
f = BytesIO(data.read())
setattr(f, 'filename', filename)
form.add_field('file', f, filename=filename, content_type=content_type)Your environment
Python 3.6.1 on Ubuntu