python - open - ssh set_missing_host_key_policy paramiko autoaddpolicy())
SFTP em Python?(plataforma independente) (6)
Aqui está uma amostra 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
O pysftp é um módulo sftp fácil de usar que utiliza paramiko e pycrypto. Ele fornece uma interface simples para o sftp. Outras coisas que você pode fazer com o 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 o PySFTP here .
Estou trabalhando em uma ferramenta simples que transfere arquivos para um local codificado com a senha também codificada. Eu sou um novato em python, mas graças ao ftplib, foi 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 nenhuma biblioteca que suporte sFTP. Qual é a maneira normal de fazer algo assim com segurança?
Edit: Graças às respostas aqui, eu comecei 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.'
Obrigado novamente!
Com a chave RSA, consulte here
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)
Paramiko é tão lento. Use subprocess e shell, 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)
Se você quiser fácil e simples, talvez queira ver o Fabric . É uma ferramenta de implementação automatizada como o Capistrano do Ruby, mas mais simples e fácil de usar para o Python. É construído em cima da Paramiko.
Você pode não querer fazer uma 'implantação automatizada', mas o Fabric adequa-se perfeitamente ao seu caso de uso. Para mostrar como o Fabric é simples: o arquivo fab e o comando do seu script ficariam assim (não testados, mas com 99% de certeza que funcionarão):
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! :)
Você pode usar o módulo pexpect
Aqui está um bom post de introdução
child = pexpect.spawn ('/usr/bin/sftp ' + [email protected].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 deve funcionar
Twisted pode ajudá-lo com o que você está fazendo, verificar sua documentação, há muitos exemplos. Também é um produto maduro com uma grande comunidade de desenvolvedores / usuários por trás dele.