Pergunta

Eu estou trabalhando em uma ferramenta simples que transfere arquivos para um local hard-coded com a senha também hard-coded. Eu sou um novato python, mas graças a ftplib, era fácil:

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)

O problema é que não consigo encontrar qualquer biblioteca que suporta SFTP. Qual é a maneira normal de fazer algo assim de forma segura?

Edit:. Graças às respostas aqui, eu comecei-o a trabalhar com paramiko e esta foi a sintaxe

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

Mais uma vez obrigado!

Foi útil?

Solução

paramiko suporta SFTP. Eu usei-o, e eu usei torcida. Ambos têm o seu lugar, mas você pode achar que é mais fácil começar com paramiko.

Outras dicas

Você deve verificar se pysftp https://pypi.python.org/pypi/pysftp isso depende de paramiko, mas wraps casos de uso mais comuns para apenas algumas linhas de código.

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 você quiser fácil e simples, que você pode também querer olhar para Tecido . É uma ferramenta de implantação automatizada como Capistrano de Ruby, mas mais simples e claro para Python. Ele foi construido em cima de paramiko.

Você não pode querer fazer 'implantação automatizada', mas Fabric se adequar ao seu caso de uso perfeitamente no entanto. Para mostrar como é simples Tecido é: o arquivo fab e comando para o seu script ficaria assim (não testado, mas 99% de certeza que ele vai trabalhar):

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

Em seguida, execute o arquivo com o comando fab:

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

E pronto! :)

Aqui está um exemplo usando pysftp e uma chave privada.

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 é um fácil de usar sftp módulo que utiliza paramiko e PyCrypto. Ele fornece uma interface simples para sftp .. Outras coisas que você pode fazer com pysftp que são bastante úteis:

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

Mais comandos e sobre PySFTP aqui .

torcida pode ajudá-lo com o que você está fazendo, consulte a sua documentação, há uma abundância de exemplos . Também é um produto maduro com uma grande comunidade de desenvolvedores / usuário por trás dele.

Você pode usar o pexpect módulo

Aqui está uma boa introdução pós

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

Eu não testei isso, mas ele deve funcionar

paramiko é tão lento. Use subprocess e da casca, aqui está um exemplo:

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)

Com o RSA Key seguida, consulte aqui

trechos:

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)

Há um monte de respostas que mencionam pysftp, assim, no evento que você quer um invólucro gerente de contexto em torno pysftp, aqui é uma solução que é ainda menos código que acaba parecendo o seguinte quando usado

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

A (mais completa) Exemplo: http: / /www.prschmid.com/2016/09/simple-opensftp-context-manager-for.html

Este gerente contexto passa a ter uma lógica auto-repetição cozido em no caso de você não pode se conectar pela primeira vez ao redor (que surpreendentemente acontece com mais freqüência do que você esperaria em um ambiente de produção ...)

O gerente essência contexto para open_sftp: https://gist.github.com/prschmid/80a19c22012e42d4d6e791c1e4eb8515

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top