Domanda

Sto lavorando a un semplice strumento che trasferisce i file in una posizione codificata con la password anch'essa codificata. Sono un principiante di Python, ma grazie a ftplib è stato facile:

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)

Il problema è che non riesco a trovare alcuna libreria che supporti sFTP. Qual è il modo normale di fare qualcosa di simile in modo sicuro?

Modifica: grazie alle risposte qui, l'ho fatto funzionare con Paramiko e questa era la sintassi.

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.'

Grazie ancora!

È stato utile?

Soluzione

Paramiko supporta SFTP. L'ho usato e ho usato Twisted. Entrambi hanno il loro posto, ma potresti trovare più facile iniziare con Paramiko.

Altri suggerimenti

Dovresti dare un'occhiata a pysftp https://pypi.python.org/pypi/pysftp dipende da paramiko, ma racchiude i casi d'uso più comuni in poche righe di codice.

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.'

Se vuoi essere facile e semplice, potresti anche voler guardare Fabric . È uno strumento di distribuzione automatizzato come Ruby Capistrano, ma più semplice e ovviamente per Python. È basato su Paramiko.

Potresti non voler fare una 'distribuzione automatizzata' ma Fabric si adatterà perfettamente al tuo caso d'uso comunque. Per mostrarti quanto è semplice Fabric: il file e il comando fab per il tuo script sarebbero così (non testati, ma sicuro al 99% funzionerà):

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

Quindi eseguire il file con il comando fab:

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

E il gioco è fatto! :)

Ecco un esempio che utilizza pysftp e una chiave privata.

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 è un modulo sftp facile da usare che utilizza paramiko e pycrypto. Fornisce una semplice interfaccia per sftp .. Altre cose che puoi fare con pysftp che sono abbastanza utili:

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

Altri comandi e informazioni su PySFTP qui .

Twisted può aiutarti in quello che stai facendo, controlla la loro documentazione, ci sono molti esempi . Inoltre è un prodotto maturo con dietro una grande comunità di sviluppatori / utenti.

Puoi utilizzare il modulo pexpect

Ecco una buona introduzione pubblicare

child = pexpect.spawn ('/usr/bin/sftp ' + user@ftp.site.com )
child.expect ('.* password:')
child.sendline (your_password)
child.expect ('sftp> ')
child.sendline ('dir')
child.expect ('sftp> ')
file_list = child.before
child.sendline ('bye')

Non l'ho provato ma dovrebbe funzionare

Paramiko è così lento. Usa sottoprocesso e shell, ecco un esempio:

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)

Con RSA Key quindi fai riferimento a qui

Snippet:

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)

Ci sono un sacco di risposte che menzionano pysftp, quindi nel caso in cui si desideri un wrapper del gestore di contesto attorno a pysftp, ecco una soluzione che è ancora meno codice che finisce per apparire come il seguente quando usato

path = "sftp://user:p@ssw0rd@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.") 

L'esempio (più completo): http: / /www.prschmid.com/2016/09/simple-opensftp-context-manager-for.html

Questo gestore di contesto ha una logica di ripetizione automatica inserita nel caso in cui non sia possibile connettersi per la prima volta (cosa che accade sorprendentemente più spesso di quanto ci si aspetterebbe in un ambiente di produzione ...)

Il gestore del contesto per open_sftp : https: //gist.github .com / prschmid / 80a19c22012e42d4d6e791c1e4eb8515

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top