Совет для запуска параллельных команд pysftp - PullRequest
0 голосов
/ 04 января 2019

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

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

Я пробовал что-то вроде этого:

class sftp:
    def __init__(self):
        self.response = HttpResponse()
        self.cnopts = pysftp.CnOpts()
        self.cnopts.hostkeys = None
    def download(self):
        with pysftp.Connection('host.exmaple.com', username='user1', password='test_password',
                               cnopts=self.cnopts) as sftp:
            sftp.getfo(
                '/var/lib/stuff/file.mp3',
                self.response)
            self.response['Content-Type'] = 'audio/mp3'
        return self.response

Тогда, на мой взгляд, я бы назвал что-то вроде этого:

return sftp().download()

1 Ответ

0 голосов
/ 04 января 2019

Мне нужно что-то подобное для одного из моих проектов.
Я написал модуль, который обрабатывает распечатку и чтение файлов на удаленном сервере по SSH.
Разница в том, что он не использует pysftp, но paramiko, ноя думаю, он должен выполнить эту работу.

import paramiko


class SSHClient:
    __slots__ = ['transport', 'sftp']

    def __init__(self, host, user, passw, port):
        """Init connection to SFTP server.
        Args:
            host (str): Server IP address
            user (str): Server username
            passw (str): Server password
            port (int): connection port
        """
        self.transport = paramiko.Transport((host, port))
        self.transport.connect(username=user, password=passw)
        self.sftp = paramiko.SFTPClient.from_transport(t=self.transport)

    def __enter__(self):
        return self

    def __exit__(self, exception_type, exception_value, traceback):
        """Close SFTP connection"""
        self.transport.close()
        self.sftp.close()

    def list_files(self, remote_path) -> list:
        """List files from specific server directory.
        Args:
            remote_path (str): SFTP server path directory.
        Returns:
            list of files & folders in directory.
        """
        return self.sftp.listdir(path=remote_path)

    def read_remote_file(self, remote_path, filename):
        """Read remote file content from server.
        Args:
            remote_path (str): SFTP server path.
            filename (str): name of file.
        """
        return self.sftp.open(
            filename='{path}/{file}'.format(path=remote_path, file=filename),
            mode='r'
        )

    def close_conn(self) -> None:
        """Close SFTP connection"""
        self.transport.close()
        self.sftp.close()

Затем вы можете загрузить файл, используя содержимое, извлеченное с помощью read_remote_file(), в один из ваших просмотров в приложении Django.

...