SFTP in Python? (Plattformunabhängig)
Frage
Ich arbeite an einem einfachen Werkzeug, das Datei auf eine hartcodierte Position mit dem Passwort überträgt auch hartcodiert. Ich bin ein Python-Neuling, 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 __name__ == '__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, die SFTP finden. Was ist der normale Weg, so etwas wie dies sicher zu tun?
Edit:. Dank der Antworten hier, ich habe es bekommen mit paramiko arbeiten 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 nochmal!
Lösung
paramiko unterstützt SFTP. Ich habe es benutzt, und ich habe verwendet Verdrehte. Beide haben ihren Platz, aber man könnte es einfacher finden mit paramiko zu starten.
Andere Tipps
Sie sollten überprüfen pysftp https://pypi.python.org/pypi/pysftp es hängt von paramiko, sondern wickelt am häufigsten Anwendungsfälle nur ein paar Zeilen Code.
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.'
Wenn Sie leicht und einfach wollen, möchten Sie vielleicht auch sehen Stoff . Es ist ein automatisiertes Deployment-Tool wie Rubys Capistrano, aber einfacher und natürlich auch für Python. Es ist bauen auf der paramiko.
Sie möchten vielleicht nicht ‚automatisierte Bereitstellung‘ zu tun, sondern Stoff würde Ihren Anwendungsfall perfekt nichtsdestoweniger entsprechen. Um Ihnen zu zeigen, wie einfach Stoff: die fab Datei und Befehl für Ihr Skript würde wie folgt aussehen (nicht getestet, aber 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
Dann die Datei mit dem fab Befehl ausführen:
fab -f fab_putfile.py put_file:file=./path/to/my/file
Und Sie sind fertig! :)
Hier wird eine Probe mit pysftp und einen 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 einfaches, SFTP-Modul zu verwenden, die paramiko und PyCrypto nutzt. Es bietet eine einfache Schnittstelle zu sftp .. Andere Dinge, die Sie mit pysftp tun können, die sehr nützlich sind:
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 über PySFTP hier .
Verdrehte helfen können, was Sie tun, überprüfen ihre Dokumentation, gibt es viele Beispiele . Auch ist es ein ausgereiftes Produkt mit einer großen Entwickler / User-Community dahinter.
Sie können mit der pexpect Modul
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')
Ich habe nicht getestet, aber es sollte funktionieren
paramiko ist so langsam. Verwenden Sie subprocess und Shell, 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)
Mit RSA Key dann finden Sie 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)
Es gibt eine Reihe von Antworten, die pysftp erwähnen, so in dem Fall, dass Sie einen Kontextmanager Wrapper um pysftp wollen, hier eine Lösung, die noch weniger Code ist, wie die folgende Suche endet, wenn verwendet,
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.")
Das (vollere) Beispiel: http: / /www.prschmid.com/2016/09/simple-opensftp-context-manager-for.html
Dieser Kontext-Manager geschieht im Falle gebacken in Auto-Retry-Logik haben, können Sie nicht das erste Mal eine Verbindung um (was überraschenderweise häufiger geschieht, als Sie in einer Produktionsumgebung erwarten würde ...)
Der Kontext-Manager Kern für open_sftp
: https://gist.github.com/prschmid/80a19c22012e42d4d6e791c1e4eb8515