2009-01-11 19 views
135

Estoy trabajando en una herramienta simple que transfiere archivos a una ubicación codificada con la contraseña también codificada. Soy un novato pitón, pero gracias a ftplib, era fácil:SFTP en Python? (plataforma independiente)

import ftplib 

info= ('someuser', 'password') #hard-coded 

def putfile(file, site, dir, user=(), verbose=True): 
    """ 
    upload a file by ftp to a site/directory 
    login hard-coded, binary transfer 
    """ 
    if verbose: print 'Uploading', file 
    local = open(file, 'rb')  
    remote = ftplib.FTP(site) 
    remote.login(*user)   
    remote.cwd(dir) 
    remote.storbinary('STOR ' + file, local, 1024) 
    remote.quit() 
    local.close() 
    if verbose: print 'Upload done.' 

if __name__ == '__main__': 
    site = 'somewhere.com'   #hard-coded 
    dir = './uploads/'    #hard-coded 
    import sys, getpass 
    putfile(sys.argv[1], site, dir, user=info) 

El problema es que no puedo encontrar ninguna biblioteca que soporta SFTP. ¿Cuál es la forma normal de hacer algo como esto de forma segura?

Editar: Gracias a las respuestas aquí, lo he conseguido trabajando con Paramiko y esta fue la sintaxis.

import paramiko 

host = "THEHOST.com"     #hard-coded 
port = 22 
transport = paramiko.Transport((host, port)) 

password = "THEPASSWORD"    #hard-coded 
username = "THEUSERNAME"    #hard-coded 
transport.connect(username = username, password = password) 

sftp = paramiko.SFTPClient.from_transport(transport) 

import sys 
path = './THETARGETDIRECTORY/' + sys.argv[1] #hard-coded 
localpath = sys.argv[1] 
sftp.put(localpath, path) 

sftp.close() 
transport.close() 
print 'Upload done.' 

¡Gracias nuevamente!

+0

Gracias! Obtuve una secuencia de comandos de carga de SFTP en 5 minutos :) –

+0

Solo una nota general sobre la pregunta original de que python ftplib también es compatible con FTPS - ftp sobre TLS https://en.m.wikipedia.org/wiki/FTPS. Los servidores FTPS son posiblemente menos utilizados en el mundo Unix, en parte debido a la omnipresencia de ssh/sftp, sin embargo, los servidores sftp están mucho menos presentes en el entorno Windows, donde FTPS es más común. – Gnudiff

Respuesta

89

Paramiko compatible con SFTP. Lo he usado, y he usado Twisted. Ambos tienen su lugar, pero puede que le resulte más fácil comenzar con Paramiko.

+2

yepp, paramiko es el camino ir (super fácil de usar), es un poco complicado encontrar el paquete de pycrypto de Windows que es una dependencia. – Mauli

+0

Gracias. Me tomó un tiempo descubrir cómo instalar el paquete debido a la falta de instrucciones de instalación en el archivo Léame, pero era exactamente lo que necesitaba. –

+15

Ver http://bitprophet.org/blog/2012/09/29/paramiko-and-ssh/ en el que Jeff Forcier explica que ssh es obsoleto y paramiko es el camino a seguir. –

3

Twisted puede ayudarlo con lo que está haciendo, consulte su documentación, hay muchos ejemplos. También es un producto maduro con una gran comunidad de desarrolladores/usuarios detrás.

+0

[Cita siempre la parte más relevante de un enlace importante, en caso de que el sitio de destino no esté disponible o permanezca fuera de línea.] (Https://stackoverflow.com/help/how-to-answer) –

14

Si quiere fácil y simple, también puede consultar Fabric. Es una herramienta de implementación automatizada como Ruby's Capistrano, pero más simple y gratuita para Python. Está construido encima de Paramiko.

Es posible que no desee realizar una "implementación automatizada", pero Fabric se adaptaría perfectamente a su caso de uso. Para mostrar cómo la tela es sencilla: el archivo de maravilla y comandos para la secuencia de comandos se vería así (no probado, pero el 99% seguro de que funcionará):

fab_putfile.py:

from fabric.api import * 

env.hosts = ['THEHOST.com'] 
env.user = 'THEUSER' 
env.password = 'THEPASSWORD' 

def put_file(file): 
    put(file, './THETARGETDIRECTORY/') # it's copied into the target directory 

A continuación, ejecute el archivo con el comando fab:

fab -f fab_putfile.py put_file:file=./path/to/my/file 

¡Y listo! :)

48

Debe revisar pysftp https://pypi.python.org/pypi/pysftp depende de paramiko, pero envuelve la mayoría de los casos de uso común a unas pocas líneas de código.

import pysftp 
import sys 

path = './THETARGETDIRECTORY/' + sys.argv[1] #hard-coded 
localpath = sys.argv[1] 

host = "THEHOST.com"     #hard-coded 
password = "THEPASSWORD"    #hard-coded 
username = "THEUSERNAME"    #hard-coded 

with pysftp.Connection(host, username=username, password=password) as sftp: 
    sftp.put(localpath, path) 

print 'Upload done.' 
+2

Vote por 'con' en el ejemplo –

+1

'pip install sftp' –

+2

' pip install pysftp' –

5

Aquí hay una muestra usando pysftp y una clave privada.

import pysftp 

def upload_file(file_path): 

    private_key = "~/.ssh/your-key.pem" # can use password keyword in Connection instead 
    srv = pysftp.Connection(host="your-host", username="user-name", private_key=private_key) 
    srv.chdir('/var/web/public_files/media/uploads') # change directory on remote server 
    srv.put(file_path) # To download a file, replace put with get 
    srv.close() # Close connection 

pysftp es un fácil utilizar el módulo de SFTP que utiliza paramiko y pycrypto. Proporciona una interfaz sencilla para sftp .. Otras cosas que se pueden hacer con pysftp que son bastante útiles:

data = srv.listdir() # Get the directory and file listing in a list 
srv.get(file_path) # Download a file from remote server 
srv.execute('pwd') # Execute a command on the server 

más comandos y sobre PySFTP here.

+0

'srv.get (file_path) # Descargar un archivo del servidor remoto' ¿Puedes explicar * dónde * descarga el archivo? –

+0

¿Has probado el local para el que fuiste ejecutado? – radtek

+0

Sí, pero ¿en qué parte del sistema de archivos? Todo transcurre con éxito, pero parece que no puedo encontrar el archivo desde ningún lado. –

0

Hay un montón de respuestas que mencionan pysftp, por lo que en el caso de que se desee un envoltorio gestor de contexto alrededor pysftp, aquí es una solución que es aún menos código que termina pareciéndose a la siguiente cuando se utiliza

path = "sftp://user:[email protected]@test.com/path/to/file.txt" 

# Read a file 
with open_sftp(path) as f: 
    s = f.read() 
print s 

# Write to a file 
with open_sftp(path, mode='w') as f: 
    f.write("Some content.") 

el (Fuller) ejemplo: http://www.prschmid.com/2016/09/simple-opensftp-context-manager-for.html

Este contexto gestor pasa a tener la lógica de auto-reintento al horno en el caso en que no se puede conectar la primera vez (que, sorprendentemente, sucede más a menudo de lo que cabe esperar de un entorno de producción ...)

El gestor de contexto para GIST open_sftp: https://gist.github.com/prschmid/80a19c22012e42d4d6e791c1e4eb8515

1

Puede utilizar el pexpect module

Here is a good intro post

child = pexpect.spawn ('/usr/bin/sftp ' + [email protected]) 
child.expect ('.* password:') 
child.sendline (your_password) 
child.expect ('sftp> ') 
child.sendline ('dir') 
child.expect ('sftp> ') 
file_list = child.before 
child.sendline ('bye') 

No he probado esto, pero debe trabajar

0

paramiko es tan lento. Utilice subproceso y concha, aquí hay un ejemplo:

remote_file_name = "filename" 
remotedir = "/remote/dir" 
localpath = "/local/file/dir" 
    ftp_cmd_p = """ 
    #!/bin/sh 
    lftp -u username,password sftp://ip:port <<EOF 
    cd {remotedir} 
    lcd {localpath} 
    get {filename} 
    EOF 
    """ 
subprocess.call(ftp_cmd_p.format(remotedir=remotedir, 
           localpath=localpath, 
           filename=remote_file_name 
           ), 
       shell=True, stdout=sys.stdout, stderr=sys.stderr) 
0

Con RSA Key a continuación se refieren here

Fragmento:

import pysftp 
import paramiko 
from base64 import decodebytes 

keydata = b"""L+WsiL5VL51ecJi3LVjmblkAdUTU+xbmXmUArIU5+8N6ua76jO/+T""" 
key = paramiko.RSAKey(data=decodebytes(keydata)) 
cnopts = pysftp.CnOpts() 
cnopts.hostkeys.add(host, 'ssh-rsa', key) 


with pysftp.Connection(host=host, username=username, password=password, cnopts=cnopts) as sftp: 
    with sftp.cd(directory): 
    sftp.put(file_to_sent_to_ftp) 
Cuestiones relacionadas