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!

Était-ce utile?

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

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top