TypeError: expected str, bytes or os.PathLike object, not _io.BytesIO

equallyhero picture equallyhero · Mar 14, 2018 · Viewed 14.1k times · Source

Trying to upload a file off the internet to my server using ssh. Have the following code that uploads local files fine, but I do not know what more to do to get the picture bytes object to upload.

from io import BytesIO
import requests
import pysftp
url = 'https://vignette.wikia.nocookie.net/disney/images/d/db/Donald_Duck_Iconic.png'

cnopts = pysftp.CnOpts()
cnopts.hostkeys = None 
response = requests.get(url)
netimage = BytesIO(response.content) #imagefromurl

srv = pysftp.Connection(host="12.34.567.89", username="root123",
password="password123",cnopts=cnopts)

with srv.cd('/var/www'): #srvdir
    #srv.put('C:\Program Files\Python36\LICENSE.txt') #local file test
    srv.put(netimage) 

print('Complete')

Answer

Martijn Pieters picture Martijn Pieters · Mar 14, 2018

You need to use the .open() method to get a file-like object, then copy across your data, using shutil.copyfileobj():

import shutil

with srv.cd('/var/www'):
    with srv.open(image_filename, 'w') as remote_file:
        shutil.copyfileobj(netimage, remote_file)

Paramiko (and by extension, pysftp) does not have any support for putting an in-memory file object directly.