pulsar icon indicating copy to clipboard operation
pulsar copied to clipboard

passing a TemporaryFile to client.HttpRequest fails

Open DavHau opened this issue 7 years ago • 0 comments

  • pulsar version: 2.0.2
  • python version: 3.6.5
  • platform: Linux/Ubuntu16.04

Description

Appending a TemporaryFile to a post request fails with this trace: File "/opt/venv/dc-venv/lib/python3.6/site-packages/pulsar/apps/http/client.py", line 919, in _request request = HttpRequest(self, url, method, params, **nparams) File "/opt/venv/dc-venv/lib/python3.6/site-packages/pulsar/apps/http/client.py", line 247, in init self.body = self._encode_body(data, files, json) File "/opt/venv/dc-venv/lib/python3.6/site-packages/pulsar/apps/http/client.py", line 369, in _encode_body body, ct = self._encode_files(data, files) File "/opt/venv/dc-venv/lib/python3.6/site-packages/pulsar/apps/http/client.py", line 407, in _encode_files fn = guess_filename(v) or k File "/opt/venv/dc-venv/lib/python3.6/site-packages/pulsar/apps/http/client.py", line 64, in guess_filename if name and name[0] != '<' and name[-1] != '>': TypeError: 'int' object is not subscriptable

The problem here seems to be that python's tempfile.TemporaryFile's filename has type int and not string. A look at the documentation of io.FileIO:

The name can be one of two things:

a character string or bytes object representing the path to the file which will be opened. In this case closefd must be True (the default) otherwise an error will be raised.
an integer representing the number of an existing OS-level file descriptor to which the resulting FileIO object will give access. When the FileIO object is closed this fd will be closed as well, unless closefd is set to False.

As a user of pulsar the issue can be prevented by using NamedTemporaryFile instead of TemporaryFile.

Expected behaviour

A TemporaryFile (which has no name) is a file like object and therefore it should be possible to pass it via the 'file' parameter to a request. (It is possible with with the 'requests' lib)

Actual behaviour

guess_filename fails during encoding the file because the filename is an int

Steps to reproduce

from pulsar.apps import http
from tempfile import TemporaryFile
import asyncio

async def request():
  with TemporaryFile() as tmpFile:
    tmpFile.write('hello world'.encode())
    tmpFile.seek(0)
    sessions = http.HttpClient()
    await sessions.post(
            'http://google.com',
            files={'file.txt': tmpFile}
    )

asyncio.get_event_loop().run_until_complete(request())

DavHau avatar Aug 09 '18 16:08 DavHau