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

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

Спасибо ! Получил скрипт загрузки SFTP, работающий за 5 минут :)

Ohad Schneider 11.03.2010 03:03

Просто общее замечание по исходному вопросу, что python ftplib также поддерживает FTPS - ftp over TLS en.m.wikipedia.org/wiki/FTPS. Серверы FTPS, возможно, меньше используются в мире Unix, отчасти из-за вездесущности ssh / sftp, однако серверы sftp гораздо меньше присутствуют в среде Windows, где FTPS более распространен.

Gnudiff 27.10.2017 11:51

Похоже, поддержка FTPS была добавлена ​​в Python 3.2 с расширенным классом источник: class ftplib.FTP_TLS (host = '', user = '', passwd = '', acct = '', keyfile = None, certfile = None, context = Нет, тайм-аут = Нет, адрес_источника = Нет)

mgrollins 06.06.2019 00:23

Я точно следил за этим и получаю ошибку "файл не найден". Я проверил использование os.path.abspath и os.path.isfile, но все еще получаю ошибки при запуске этого скрипта. Что происходит?

Arthur Bowers 03.03.2021 18:23
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
193
4
204 826
11
Перейти к ответу Данный вопрос помечен как решенный

Ответы 11

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

Ответ принят как подходящий

Парамико поддерживает SFTP. Я использовал его, и я использовал Twisted. У обоих есть свое место, но, возможно, вам будет проще начать с Парамико.

yepp, paramiko - это путь (очень простой в использовании), немного сложно найти пакет Windows для pycrypto, который является зависимостью.

Mauli 11.01.2009 11:52

Спасибо. Мне потребовалось время, чтобы понять, как установить пакет, из-за отсутствия инструкций по установке в readme, но это было именно то, что мне было нужно!

Mark Wilbur 11.01.2009 14:57

См. bitprophet.org/blog/2012/09/29/paramiko-and-ssh, в котором Джефф Форсьер объясняет, что ssh устарел, а paramiko - это путь вперед.

Christopher Mahan 30.09.2012 11:10

Также есть code.google.com/p/pysftp, основанный на Paramiko, но более простой в использовании

franzlorenzon 08.02.2013 18:08

Обратите внимание, что Paramiko в настоящее время не поддерживает аутентификацию с помощью нескольких методов (например, пароля и закрытого ключа). См. github.com/paramiko/paramiko/issues/519.

Symmetric 14.12.2016 23:56

также остерегайтесь лицензии ....

Travis Webb 11.02.2021 02:18

Если вам нужно легкое и простое, вы также можете взглянуть на Ткань. Это инструмент автоматического развертывания, подобный Ruby's 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's copied into the target directory

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

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

И вы сделали! :)

Я следил за этим и получил сообщение «Не могу найти коллекцию с именем fabfile!» когда я запускаю файл python.

Arthur Bowers 03.03.2021 14:55

Вы должны проверить 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.'

Проголосуйте за with в примере

Roman Podlinov 24.07.2014 18:07
pip install pysftp
Bob Stein 20.01.2016 15:33

Есть ли возможность автоматически добавлять новый хост sftp к известным хостам?

user443854 27.07.2016 21:39

@ user443854 да, есть pysftp.readthedocs.io/en/release_0.2.9/…, но я бы определенно не рекомендовал это, хотя вы можете добавить еще один файл known_host

AsTeR 17.07.2018 11:04

ВНИМАНИЕ: похоже, что pysftp больше не очень активен. Ссылка на систему отслеживания проблем на их сайте не работает (говорит, что она не настроена). Я обнаружил ошибку и пытаюсь найти лучший способ ее задокументировать и исправить, но не похоже, что она обновлялась более 4 лет.

JD D 25.08.2020 23:47

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

srv.get(file_path) # Download a file from remote server вы можете объяснить где загружает ли он файл?
Markus Meskanen 29.06.2017 13:04

Вы пробовали местный для вас казненный?

radtek 04.07.2017 20:19

Да, но где в файловой системе? Все проходит успешно, но я не могу найти файл нигде.

Markus Meskanen 05.07.2017 09:45

Извините, я имел в виду местный реж. Попробуйте выполнить сценарий из домашнего каталога и посмотрите, есть ли там файл.

radtek 05.07.2017 18:39

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

path = "sftp://user:p@[email protected]/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

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

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

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)

Речь идет о «Python», что обычно подразумевает соблюдение этого принципа, особенно когда есть так много вариантов для этого. Что еще более важно, в нем написано «Независимо от платформы». Я не могу сказать, работает ваш ответ быстрее или нет. Возможно?

BuvinJ 29.04.2020 03:40

С RSA Key затем обратитесь к здесь

Фрагмент:

import pysftp
import paramiko
from base64 import decodebytes

keydata = b"""AAAAB3NzaC1yc2EAAAADAQABAAABAQDl""" 
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)

PyFilesystem с его sshfs - один из вариантов. Он использует Paramiko под капотом и обеспечивает более приятный независимый интерфейс сверху.

import fs

sf = fs.open_fs("sftp://[user[:password]@]host[:port]/[directory]")
sf.makedir('my_dir')

или же

from fs.sshfs import SSHFS
sf = SSHFS(...

fsspec - отличный вариант для этого, он предлагает файловую систему, подобную реализации sftp.

from fsspec.implementations.sftp import SFTPFileSystem
fs = SFTPFileSystem(host=host, username=username, password=password)

# list a directory
fs.ls("/")

# open a file
with fs.open(file_name) as file:
    content = file.read()

Также стоит отметить, что fsspec использует paramiko в выполнение.

Другие вопросы по теме