programing

Python의 SFTP(플랫폼에 의존하지 않음)

bestcode 2022. 9. 24. 12:42
반응형

Python의 SFTP(플랫폼에 의존하지 않음)

비밀번호를 하드코딩해서 파일을 하드코딩된 곳으로 전송하는 간단한 도구를 만들고 있습니다.나는 비단뱀 초보지만 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를 지원합니다.나도 써봤고 트위스트도 써봤지둘 다 각자의 자리가 있지만, 파라미코부터 시작하는 것이 더 쉬울지도 모른다.

pysftp https://pypi.python.org/pypi/pysftp을 참조하십시오.파라미코에 의존하지만 대부분의 일반적인 사용 사례는 몇 줄의 코드로 정리됩니다.

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

여기 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 모듈이다.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에 대한 자세한 내용은 여기를 참조하십시오.

쉽고 심플하게 하고 싶은 경우는, Fabric도 검토해 주세요.이것은 Ruby's Capistrano와 같은 자동화된 배포 도구이지만, Python은 물론 더 단순합니다.파라미코 위에 지어졌어요

'자동 도입'을 하고 싶지 않을 수도 있지만 패브릭은 사용 사례에 매우 적합합니다.패브릭의 심플함을 나타냅니다.스크립트의 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

이것으로 끝! :)

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)

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를 구현에 사용한다는 점도 주목할 필요가 있습니다.

Twisted는 작업에 도움이 될 수 있으며 문서도 참조할 수 있습니다. 예는 많습니다.또한 대규모 개발자/사용자 커뮤니티가 있는 성숙한 제품입니다.

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

파라미코는 너무 느리다.서브프로세스와 셸을 사용합니다.다음은 예를 제시하겠습니다.

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)

sshfs가 있는 PyFilesystem도 옵션 중 하나입니다.후드 아래에 파라미코를 사용하고, 상부에 보다 멋진 팰트폼 독립 인터페이스를 제공합니다.

import fs

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

또는

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

지정된 경로에 지정된 sftp URL을 다운로드하는 일반 함수는 다음과 같습니다.

from urllib.parse import urlparse
import paramiko

url = 'sftp://username:password@hostname/filepath.txt'

def sftp_download(url, dest):
    url = urlparse(url)
    with paramiko.Transport((url.hostname, 22)) as transport:
        transport.connect(None,url.username,url.password)
        with paramiko.SFTPClient.from_transport(transport) as sftp:
            sftp.get(url.path, dest)

로 전화하다

sftp_download(url, "/tmp/filepath.txt")

언급URL : https://stackoverflow.com/questions/432385/sftp-in-python-platform-independent

반응형