Найти - Пользователи
Полная версия: Функция для рекурсивной загрузки каталога по SFTP
Начало » Python для новичков » Функция для рекурсивной загрузки каталога по SFTP
1
VIRTOK
Нужна функция для рекурсивной загрузки каталога с SFTP
Прошу помочь разобраться как работает функция
 import paramiko, os
paramiko.util.log_to_file('/tmp/paramiko.log')
from stat import S_ISDIR
host = "ip"
port = 22
transport = paramiko.Transport((host, port))
password = "mypassword"
username = "username"
transport.connect(username = username, password = password)
sftp = paramiko.SFTPClient.from_transport(transport)
def sftp_walk(remotepath):
    path=remotepath
    files=[]
    folders=[]
    for f in sftp.listdir_attr(remotepath):
        if S_ISDIR(f.st_mode):
            folders.append(f.filename)
        else:
            files.append(f.filename)
    if files:
        yield path, files
    for folder in folders:
        new_path=os.path.join(remotepath,folder)
        for x in sftp_walk(new_path):
            yield x
for path,files  in sftp_walk("." or '/remotepath/'):
    for file in files:
        #sftp.get(remote, local) line for dowloading.
        sftp.get(os.path.join(os.path.join(path,file)), '/local/path/')
py.user.next
VIRTOK
Прошу помочь разобраться как работает функция
Обычная рекурсивная функция, ничего особенного.
Как работает:
1)
Для заданной директории получает список файлов и директорий.
2)
Если элемент списка - файл, то возвращает для него информацию.
3)
Если элемент списка - директория, то запускает саму себя для этой директории как для изначальной и возвращает информацию, полученную из подвызова.

Почитай про рекурсивные функции.
Здесь подборка моих описаний рекурсии.
VIRTOK
Написал следующий код теперь могу скачивать 1 файл , каталог скачивать не получается.

 #Host SFTP сервера
host = "test.rebex.net"
#Port SFTP сервера
port = 22
#Имя пользователя для подключения к SFTP серверу
username = "demo"
#Пароль для подключения к SFTP серверу
password = "password"
#####################################################################
import paramiko, os
from stat import S_ISDIR
#Включаем логи
paramiko.util.log_to_file('D:\\Lessons_Python\\paramiko.log')
#Используем функцию для соединения по SSH
ssh = paramiko.SSHClient()
#Получаем ключ для подключения по SSH
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
#Устанавливаем соединение с sftp
#Используя host ,username, password
sftp_connect = ssh.connect(host, username=username,password=password)
#Открываем соединение с SFTP
sftp=ssh.open_sftp()
#####################################################################
def sftp_walk(remotepath):
    path=remotepath
    files=[]
    folders=[]
    for f in sftp.listdir_attr(remotepath):
        if S_ISDIR(f.st_mode):
            folders.append(f.filename)
        else:
            files.append(f.filename)
    if files:
        yield path, files
    for folder in folders:
        new_path=os.path.join(remotepath,folder)
        for x in sftp_walk(new_path):
            yield x
for path,files  in sftp_walk("."):
    for file in files:
        #sftp.get(remote, local) line for dowloading.
        sftp.get(os.path.join(os.path.join(path,file)), 'D:\\Lessons_Python\\readme.txt')
uf4JaiD5
Для начала
 sftp.get(os.path.join(os.path.join(path,file)), 'D:\\Lessons_Python\\readme.txt')
заменить на:
 sftp.get(os.path.join(path,file), os.path.join('D:\\Lessons_Python', file))

А потом начать разбирать path, чтоб сохранялась структура каталогов. sftp.get же сам несуществующие в ‘D:\\Lessons_Python’ каталоги не создаст?
VIRTOK
Теперь программа работает ,но закачивает все файлы из всех папок в одну
рекурсивная загрузка каталогов не происходит.
 #Host SFTP сервера
host = "test.rebex.net"
#Port SFTP сервера
port = 22
#Имя пользователя для подключения к SFTP серверу
username = "demo"
#Пароль для подключения к SFTP серверу
password = "password"
#####################################################################
import paramiko, os
from stat import S_ISDIR
#Включаем логи
paramiko.util.log_to_file('D:\\Lessons_Python\\paramiko.log')
#Используем функцию для соединения по SSH
ssh = paramiko.SSHClient()
#Получаем ключ для подключения по SSH
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
#Устанавливаем соединение с sftp
#Используя host ,username, password
sftp_connect = ssh.connect(host, username=username,password=password)
#Открываем соединение с SFTP
sftp=ssh.open_sftp()
#####################################################################
def sftp_walk(remotepath):
    path=remotepath
    files=[]
    folders=[]
    for f in sftp.listdir_attr(remotepath):
        if S_ISDIR(f.st_mode):
            folders.append(f.filename)
        else:
            files.append(f.filename)
    if files:
        yield path, files
    for folder in folders:
        new_path=os.path.join(remotepath,folder)
        for x in sftp_walk(new_path):
            yield x
for path,files  in sftp_walk("."):
    for file in files:
        #sftp.get(remote, local) line for dowloading.
         sftp.get(os.path.join(path,file), os.path.join('D:\\Lessons_Python', file))[u][/u]
VIRTOK
Нужно сохранять структуру каталогов и их содержимое в таком виде в котором они лежат на сервере.
JOHN_16
одно из основных правил - не выкладывайте публично реальные ключи доступа к сереврам и/или аккаунтам.
uf4JaiD5
VIRTOK
Нужно сохранять структуру каталогов и их содержимое в таком виде в котором они лежат на сервере.
Примерно так
 #
from os.path import exists
from os import mkdir
from pathlib import Path
...
for path,files  in sftp_walk("."):
    localpath = 'D:\\Lessons_Python'
    for p in Path(path).parts:
        localpath = join(localpath, p)
        if not exists(localpath):
            mkdir(localpath)
    for file in files:
        #sftp.get(remote, local) line for dowloading.
         sftp.get(os.path.join(path,file), os.path.join(localpath, file))
VIRTOK
JOHN_16
одно из основных правил - не выкладывайте публично реальные ключи доступа к сереврам и/или аккаунтам.
Спасибо за предупреждение ,но это публичный SFTP для тестирования,им может воспользоваться каждый. Так что все хорошо .

VIRTOK
Нужно что бы файлы с SFTP попадали не в один каталог , а создавались точно такие же каталоги как на SFTP на локальном компьютере.

На данном этапе получаем код:

 #Host SFTP сервера
host = "test.rebex.net"
#Port SFTP сервера
port = 22
#Имя пользователя для подключения к SFTP серверу
username = "demo"
#Пароль для подключения к SFTP серверу
password = "password"
#######################################################################################################################
import paramiko, os
from stat import S_ISDIR
#Включаем логи
paramiko.util.log_to_file('D:\\Lessons_Python\\paramiko.log')
#Используем функцию для соединения по SSH
ssh = paramiko.SSHClient()
#Получаем ключ для подключения по SSH
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
#Устанавливаем соединение с sftp
#Используя host ,username, password
sftp_connect = ssh.connect(host, username=username,password=password)
#Открываем соединение с SFTP
sftp=ssh.open_sftp()
def sftp_connect():
#Включаем логи
    paramiko.util.log_to_file('D:\\Рaramiko\\paramiko.log')
#Используем функцию для соединения по SSH
    ssh = paramiko.SSHClient()
#Получаем ключ для подключения по SSH
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
#Устанавливаем соединение с sftp
#Используя host ,username, password
    sftp_connect = ssh.connect(host, username=username,password=password)
#Открываем соединение с SFTP
    sftp=ssh.open_sftp()
def sftp_walk(remotepath):
    path=remotepath
    files=[]
    folders=[]
    for f in sftp.listdir_attr(remotepath):
        if S_ISDIR(f.st_mode):
            folders.append(f.filename)
        else:
            files.append(f.filename)
    if files:
        yield path, files
    for folder in folders:
        new_path=os.path.join(remotepath,folder)
        for x in sftp_walk(new_path):
            yield x
for path,files  in sftp_walk("."):
    for file in files:
        #sftp.get(remote, local) line for dowloading.
        sftp.get(os.path.join(path,file), os.path.join('D:\\Рaramiko\\', file))
Результат
1.Файлы из всех папок на сервера SFTP загружаются в один каталог.
2. Получаем ошибку после выполнения скрипта
 C:\Users\Users\AppData\Local\Programs\Python\Python37-32\python.exe D:/Рaramiko/Рaramiko_SFTP.py
C:\Users\Users\AppData\Local\Programs\Python\Python37-32\lib\site-packages\paramiko\kex_ecdh_nist.py:39: CryptographyDeprecationWarning: encode_point has been deprecated on EllipticCurvePublicNumbers and will be removed in a future version. Please use EllipticCurvePublicKey.public_bytes to obtain both compressed and uncompressed point encoding.
  m.add_string(self.Q_C.public_numbers().encode_point())
C:\Users\Pavel\AppData\Local\Programs\Python\Python37-32\lib\site-packages\paramiko\kex_ecdh_nist.py:96: CryptographyDeprecationWarning: Support for unsafe construction of public numbers from encoded data will be removed in a future version. Please use EllipticCurvePublicKey.from_encoded_point
  self.curve, Q_S_bytes
C:\Users\Users\AppData\Local\Programs\Python\Python37-32\lib\site-packages\paramiko\kex_ecdh_nist.py:111: CryptographyDeprecationWarning: encode_point has been deprecated on EllipticCurvePublicNumbers and will be removed in a future version. Please use EllipticCurvePublicKey.public_bytes to obtain both compressed and uncompressed point encoding.
  hm.add_string(self.Q_C.public_numbers().encode_point())
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB