Me gustaría cargar varios archivos desde un directorio de Windows a un servidor SFTP usando pysftp 0.2.8. He leído el documento y sugiere usar put_d o put_r pero ambos me dan el siguiente error:

OSError: ruta no válida:

sftp_local_path = r'C:\Users\Swiss\some\path'

sftp_remote_path = '/FTP/LPS Data/ATC/RAND/20191019_RAND/XML'

with pysftp.Connection("xxx.xxx.xxx.xxx", username=myUsername, password=myPassword) as sftp:
    with sftp.cd(sftp_remote_path):
        sftp.put_r(sftp_local_path, sftp_remote_path)
        for i in sftp.listdir():
            lstatout=str(sftp.lstat(i)).split()[0]
            if 'd' in lstatout: print (i, 'is a directory')

sftp.close()

Me gustaría poder copiar todos los archivos o archivos seleccionados de mi directorio local al servidor SFTP.

1
MdM 19 oct. 2019 a las 08:14

1 respuesta

La mejor respuesta

No puedo reproducir su problema exacto, pero de hecho se sabe que las funciones recursivas de pysftp se implementan de una manera que hace que fallen en Windows (o en cualquier sistema que no use la sintaxis de ruta * nix-like).

Pysftp usa funciones os.sep y os.path para rutas SFTP remotas, lo que está mal, ya que las rutas SFTP siempre usan una barra inclinada.


Pero puede implementar fácilmente un reemplazo portátil:

import os
def put_r_portable(sftp, localdir, remotedir, preserve_mtime=False):
    for entry in os.listdir(localdir):
        remotepath = remotedir + "/" + entry
        localpath = os.path.join(localdir, entry)
        if not os.path.isfile(localpath):
            try:
                sftp.mkdir(remotepath)
            except OSError:     
                pass
            put_r_portable(sftp, localpath, remotepath, preserve_mtime)
        else:
            sftp.put(localpath, remotepath, preserve_mtime=preserve_mtime)    

Úselo como:

put_r_portable(sftp, sftp_local_path, sftp_remote_path, preserve_mtime=False) 

Para una pregunta similar sobre get_r, consulte:
Python pysftp get_r de Linux funciona bien en Linux pero no en Windows

4
Martin Prikryl 4 ene. 2021 a las 09:11