SFTP en Python? (indépendant de la plateforme)
Question
Je travaille sur un outil simple qui transfère les fichiers vers un emplacement codé en dur avec le mot de passe également codé en dur. Je suis un novice en python, mais grâce à ftplib, c'était 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)
Le problème est que je ne trouve aucune bibliothèque prenant en charge sFTP. Quelle est la façon normale de faire quelque chose comme ça en toute sécurité?
Edit: Merci aux réponses fournies ici, je l’ai obtenu avec Paramiko et c’était la syntaxe.
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.'
Merci encore!
La solution
Paramiko prend en charge le protocole SFTP. Je l'ai utilisé et j'ai utilisé Twisted. Les deux ont leur place, mais vous trouverez peut-être plus facile de commencer par Paramiko.
Autres conseils
Vous devriez consulter pysftp https://pypi.python.org/pypi/pysftp . cela dépend de paramiko, mais résume les cas d'utilisation les plus courants à quelques lignes de 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.'
Si vous voulez un jeu d'enfant, vous pouvez également consulter Fabric . C'est un outil de déploiement automatisé comme Capistrano de Ruby, mais plus simple et bien sûr pour Python. Il est construit sur Paramiko.
Vous ne voudrez peut-être pas faire de "déploiement automatisé", mais Fabric conviendrait parfaitement à votre cas d'utilisation néanmoins. Pour vous montrer à quel point Fabric est simple: le fichier fab et la commande de votre script ressemblent à ceci (non testé, mais il est sûr à 99% que cela fonctionnera):
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
Ensuite, exécutez le fichier avec la commande fab:
fab -f fab_putfile.py put_file:file=./path/to/my/file
Et vous avez terminé! :)
Voici un exemple utilisant pysftp et une clé privée.
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 est un module sftp facile à utiliser, qui utilise paramiko et pycrypto. Il fournit une interface simple à sftp .. Voici d'autres choses que vous pouvez faire avec pysftp qui sont très utiles:
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
Autres commandes et informations sur PySFTP ici .
Twisted peut vous aider avec ce que vous faites, consultez leur documentation, il existe de nombreux exemples . C'est aussi un produit mature avec une grande communauté de développeurs / utilisateurs.
Vous pouvez utiliser le module pexpect
.Voici une bonne introduction publier
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')
Je n'ai pas testé cela, mais cela devrait fonctionner
Paramiko est si lent. Utilisez un sous-processus et un shell, voici un exemple:
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)
Avec RSA Key, reportez-vous ensuite à ici
.Extrait:
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)
Il existe de nombreuses réponses mentionnant pysftp. Par conséquent, dans le cas où vous souhaitez un gestionnaire de contexte autour de pysftp, voici une solution contenant encore moins de code qui ressemble finalement à ce qui suit
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'exemple (le plus complet): http: / /www.prschmid.com/2016/09/simple-opensftp-context-manager-for.html
Ce gestionnaire de contexte a une logique de nouvelle tentative automatique intégrée si vous ne pouvez pas vous connecter la première fois (ce qui est surprenant plus souvent que prévu dans un environnement de production ...)
L'essentiel du gestionnaire de contexte pour open_sftp
: https: //gist.github .com / prschmid / 80a19c22012e42d4d6e791c1e4eb8515