it-swarm.com.de

SFTP in Python? (Plattformunabhängig)

Ich arbeite an einem einfachen Tool, das Dateien an einen fest codierten Speicherort überträgt, wobei das Kennwort ebenfalls fest codiert ist. Ich bin ein python Anfänger, aber dank ftplib war es einfach:

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 __== '__main__':
    site = 'somewhere.com'            #hard-coded
    dir = './uploads/'                #hard-coded
    import sys, getpass
    putfile(sys.argv[1], site, dir, user=info)

Das Problem ist, dass ich keine Bibliothek finde, die sFTP unterstützt. Was ist der normale Weg, um so etwas sicher zu machen?

Edit: Dank der Antworten hier habe ich es mit Paramiko zum Laufen gebracht und dies war die Syntax.

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

Danke noch einmal!

166
Mark Wilbur

Paramiko unterstützt SFTP. Ich habe es benutzt und ich habe Twisted benutzt. Beide haben ihren Platz, aber vielleicht fällt es Ihnen leichter, mit Paramiko zu beginnen.

102
Brian Clapper

Sie sollten pysftp https://pypi.python.org/pypi/pysftp auschecken, es hängt von paramiko ab, bricht jedoch die häufigsten Anwendungsfälle in nur wenige Codezeilen um.

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.'
62
Dundee MT

Wenn Sie einfach und unkompliziert möchten, sollten Sie sich auch Fabric ansehen. Es ist ein automatisiertes Bereitstellungstool wie Ruby's Capistrano, aber einfacher und natürlich für Python. Es basiert auf Paramiko.

Möglicherweise möchten Sie keine automatische Bereitstellung durchführen, aber Fabric passt trotzdem perfekt zu Ihrem Anwendungsfall. Um Ihnen zu zeigen, wie einfach Fabric ist: Die Fab-Datei und der Befehl für Ihr Skript sehen folgendermaßen aus (nicht getestet, aber zu 99% sicher, dass es funktionieren wird):

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

Führen Sie dann die Datei mit dem Befehl fab aus:

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

Und du bist fertig! :)

15
hopla

Hier ein Beispiel mit pysftp und einem privaten Schlüssel.

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 ist ein benutzerfreundliches SFTP-Modul, das Paramiko und Pycrypto verwendet. Es bietet eine einfache Schnittstelle zu sftp. Andere Dinge, die Sie mit pysftp tun können, sind sehr nützlich:

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

Weitere Befehle und zu PySFTP hier .

8
radtek

Twisted kann Ihnen helfen, was Sie tun, überprüfen Sie die Dokumentation, es gibt viele Beispiele. Es ist auch ein ausgereiftes Produkt mit einer großen Entwickler-/Benutzergemeinschaft dahinter.

3

Mit RSA-Schlüssel beziehen Sie sich dann auf hier

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)
1
Abhijeet

Paramiko ist so langsam. Unterprozess und Shell verwenden, hier ein Beispiel:

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)
1
杨李思

Sie können das pexpect-Modul verwenden

Hier ist ein guter Intro-Beitrag

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

Ich habe das nicht getestet, aber es sollte funktionieren

1
MIkee

Es gibt eine Reihe von Antworten, in denen pysftp erwähnt wird. Für den Fall, dass Sie einen Kontextmanager-Wrapper für pysftp benötigen, finden Sie hier eine Lösung, die noch weniger Code enthält, der bei Verwendung wie folgt aussieht

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.") 

Das (ausführlichere) Beispiel: http://www.prschmid.com/2016/09/simple-opensftp-context-manager-for.html

In diesem Kontextmanager ist zufällig eine automatische Wiederholungslogik eingebaut, falls Sie beim ersten Mal keine Verbindung herstellen können (was überraschenderweise häufiger vorkommt, als Sie es in einer Produktionsumgebung erwarten würden ...).

Der Kontextmanager Gist für open_sftp: https://Gist.github.com/prschmid/80a19c22012e42d4d6e791c1e4eb8515

0
prschmid