SFTP в Python? (независимая платформа)

Я работаю над простым инструментом, который передает файлы в жестко закодированное местоположение, причем пароль также жестко закодирован. Я начинающий python, но благодаря ftplib это было просто:

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) 

Проблема в том, что я не могу найти библиотеку, которая поддерживает sFTP. Каков нормальный способ сделать что-то подобное безопасно?

Редактирование: благодаря ответам здесь я получил работу с Paramiko, и это был синтаксис.

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

Еще раз спасибо!

  • скрученный конвертер
  • Использовать подпроцесс для отправки пароля
  • Соединение PySFTP работает, но get () не работает
  • 9 Solutions collect form web for “SFTP в Python? (независимая платформа)”

    Парамико поддерживает SFTP. Я использовал его, и я использовал Twisted. Оба имеют свое место, но вам может быть легче начать с Парамико.

    Вы должны проверить pysftp https://pypi.python.org/pypi/pysftp, это зависит от paramiko, но обертывает наиболее распространенные случаи использования всего несколькими строками кода.

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

    Если вы хотите легко и просто, вы также можете посмотреть на Fabric . Это инструмент автоматического развертывания, такой как Rubist's Capistrano, но более простой и простой для Python. Он построен на вершине Парамико.

    Возможно, вы не захотите делать «автоматическое развертывание», но Fabric идеально подойдет вашему прецеденту. Чтобы показать вам, как простая ткань: файл fab и команда для вашего скрипта будут выглядеть так (не проверены, но на 99% уверены, что это сработает):

    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 

    Затем запустите файл командой fab:

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

    И вы сделали! 🙂

    Я бы придерживался чистого решения Python , но это не так, что нет параметров Windows ssh. Например, у Cygwin есть один, и их гораздо больше .

    Вот пример с использованием pysftp и закрытого ключа.

     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 – простой в использовании модуль sftp, который использует paramiko и pycrypto. Он предоставляет простой интерфейс для sftp .. Другие вещи, которые вы можете сделать с pysftp, которые весьма полезны:

     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 

    Дополнительные команды и PySFTP здесь .

    Twisted может помочь вам в том, что вы делаете, проверить их документацию, есть много примеров. Также это зрелый продукт с большим сообществом разработчиков / пользователей за ним.

    Вы можете использовать модуль pexpect

    Вот хороший вводный пост

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

    Я не тестировал это, но он должен работать

    Есть куча ответов, в которых упоминается pysftp, поэтому в случае, если вы хотите, чтобы обертка менеджера контекста вокруг pysftp, это решение, которое еще меньше кода, который выглядит следующим образом, когда используется

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

    Пример (более полный): http://www.prschmid.com/2016/09/simple-opensftp-context-manager-for.html

    У этого менеджера контекста есть автоматическая повторная логика, испеченная в том случае, если вы не можете подключиться в первый раз (что удивительно происходит чаще, чем вы ожидаете в производственной среде …)

    Менеджер контекста для open_sftp : https://gist.github.com/prschmid/80a19c22012e42d4d6e791c1e4eb8515

    Парамико настолько медленная. Используйте подпроцесс и оболочку, вот пример:

     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) 
    Python - лучший язык программирования в мире.