Ответ 1
Paramiko поддерживает SFTP. Я использовал это, и я использовал Twisted. Оба имеют свое место, но вам может быть легче начать с Paramiko.
Я работаю над простым инструментом, который передает файлы в жестко закодированное местоположение, причем пароль также жестко закодирован. Я начинающий 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.'
Еще раз спасибо!
Paramiko поддерживает SFTP. Я использовал это, и я использовал Twisted. Оба имеют свое место, но вам может быть легче начать с Paramiko.
Вы должны проверить 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.'
Если вы хотите легко и просто, вы также можете посмотреть на ткани. Это инструмент автоматического развертывания, такой как Ruby Capistrano, но более простой и, конечно, для Python. Он построен на вершине Парамико.
Возможно, вы не захотите делать "автоматическое развертывание", но Fabric идеально подойдет для вашего случая использования. Чтобы показать вам, насколько простой 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 copied into the target directory
Затем запустите файл с помощью команды fab:
fab -f fab_putfile.py put_file:file=./path/to/my/file
И вы сделали! :)
Вот пример с использованием 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 здесь.
Я бы придерживался чистого Python, но это неправда, что нет параметров Windows ssh. Cygwin имеет один, например, и еще много.
Twisted может помочь вам в том, что вы делаете, проверить их документацию, есть много примеров. Также это зрелый продукт с большим сообществом разработчиков/пользователей за ним.
Вы можете использовать pexpect module
child = pexpect.spawn ('/usr/bin/sftp ' + [email protected] )
child.expect ('.* password:')
child.sendline (your_password)
child.expect ('sftp> ')
child.sendline ('dir')
child.expect ('sftp> ')
file_list = child.before
child.sendline ('bye')
Я не тестировал это, но он должен работать
Парамико настолько медленная. Используйте подпроцесс и оболочку, вот пример:
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)
С помощью RSA Key, пожалуйста, напишите здесь
Отрывок:
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)
Есть несколько ответов, в которых упоминается pysftp, поэтому в случае, если вы хотите, чтобы обертка менеджера контекста вокруг pysftp, это решение, которое еще меньше кода, которое выглядит следующим образом при использовании
path = "sftp://user:[email protected]@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