pysftp로 파일 업로드 하기

pysftp로 파일 업로드 하기

최근에 sftp로 파일을 업로드 하는 파이썬 스크립트를 쓸 일이 있어서 코드 공유.


우선은 pip을 이용하여 pysftp 패키지를 설치

pip install pysftp
pysftp 설치 커맨드

그 다음은 아래 코드를 사용해주면 된다. 유의 할 점은 해당 호스트에 처음 접속을 시도 하는거라면 스크립트를 실행하는 서버에 호스트에 대한 호스트키가 없기 때문에, 따로 설정을 해주지 않으면 호스트에 접속이 되지 않는다.

이 문제를 해결하기 위해서는 크게 두가지 방법이 있다.

  1. 호스트키 파일에 수동으로 호스트키 정보를 입력해준다.
  2. 첫 접속 시도 때에는 호스트키를 확인하지 않고 접속을 한 다음, 접속이 된 후 sftp 서버에서 돌려주는 호스트키 정보를 업데이트 한다.

첫번째 방법은 보통 리눅스나 맥에서 호스트키 파일은 "~/ssh/known_hosts"에 저장이 되기 때문에, 이 파일을 열어서 직접 호스트와 호스트키 정보를 추가해주면 된다.

두번째 방법은 pysftp기준으로 cnopts.hostkeys 의 설정을 None 으로 설정해줌으로써 호스트키를 확인하는 단계를 무시하고 건너 뛸 수 있다. 하지만 매번 호스트키를 확인하는 설정을 무시하여 접속한다면 보안상 좋지 않고, sftp를 사용하는 의미가 퇴색됨으로, 처음 접속이 성공한 후, 서버의 호스트키 파일을 업데이트 해주는 코드를 추가해주어야한다.

import pysftp

host = '호스트명' # 호스트명만 입력. sftp:// 는 필요하지 않다.
port = 193 # int값으로 sftp서버의 포트 번호를 입력
username = '유저' # 서버 유저명
password = '비밀번호' # 유저 비밀번호

hostkeys = None

# 서버에 저장되어 있는 모든 호스트키 정보를 불러오는 코드
cnopts = pysftp.CnOpts()

# 접속을 시도하는 호스트에 대한 호스트키 정보가 존재하는지 확인
# 존재하지 않으면 cnopts.hostkeys를 None으로 설정해줌으로써 첫 접속을 가능하게 함
if cnopts.hostkeys.lookup(host) == None:
    print("Hostkey for " + host + " doesn't exist")
    hostkeys = cnopts.hostkeys # 혹시 모르니 다른 호스트키 정보들 백업
    cnopts.hostkeys = None

# 첫 접속이 성공하면, 호스트에 대한 호스트키 정보를 서버에 저장.
# 두번째 접속부터는 호스트키를 확인하며 접속하게 됨.

# sftp 접속을 실행
with pysftp.Connection(
                        host,
                        port = port,
                        username = username,
                        password = password,
                        cnopts = cnopts) as sftp:
    
    # 접속이 완료된 후 이 부분이 호스트키를 저장하는 부분
    # 처음 접속 할 때만 실행되는 코드
    if hostkeys != None:
        print("New Host. Caching hostkey for " + host)
        hostkeys.add(host, sftp.remote_server_key.get_name(), sftp.remote_server_key) # 호스트와 호스트키를 추가
        hostkeys.save(pysftp.helpers.known_hosts()) # 새로운 호스트 정보 저장

    # 폴더에 있는 모든 파일들을 한거번에 업로드 하고 싶을 땐 'put_d' 를 사용
    # 예) sftp.put_d('업로드 할 파일들이 있는 폴더 경로', '/')
    
    # 여러 파일들을 개별로 업로드 하고 싶을 땐 'put'을 여러번 사용
    # 예) sftp.put('파일1 경로')
    # 예) sftp.put('파일2 경로')
    
    # sftp서버에 있는 파일과 폴더들을 보고 싶을 땐 아래 함수 실행
    print(sftp.listdir('/'))
    
    # 모든 작업이 끝나면 접속 종료
    sftp.close()
pysftp 예재 코드

주기적으로 자동으로 업로드해야 하는 작업이 있다면 bash 스크립트를 작성하여 cron 설정을 해주면 오토메이션 완성!

그 외에 다른 기능들은 pysftp 공식 홈페이지를 참조!