Вопрос

Я работаю над простым инструментом, который переносит файлы в жестко заданное местоположение с также жестко заданным паролем.Я новичок в 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'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

И все готово!:)

Вот пример использования 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')

Я не проверял это, но оно должно работать

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

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 затем обратитесь к здесь

Фрагмент текста:

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: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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top