Python

[Python] Python에서 SFTP 구현하기

명도환 2025. 3. 12. 13:56

이 문서에서 Python의 Paramiko 라이브러리를 활용해 SFTP를 통한 파일 전송 방식을 설명합니다.

간단한 코드와 함께 주요 기능을 작성합니다.


개발환경

- Python 3.9

- Paramiko 라이브러리


Paramiko

Paramiko란?

- Paramiko는 Python에서 SSH(보안 셸) 프로토콜을 통해 원격 서버와 안전한 연결을 구축하고, 파일 전송(SFTP)이나 명령 실행과 같은 작업을 수행할 수 있도록 도와주는 라이브러리입니다. 특히, SFTP를 통해 원격 서버에서 파일을 업로드하거나 다운로드하는 기능을 지원하며, SSH를 기반으로 하므로 높은 보안성을 제공합니다.

 

Paramiko 사용 이유

  Paramiko
보안성 SSH 프로토콜을 기반으로 하여 데이터 전송 시 암호화 기능 지원, 네트워크 환경에서 민감한 파일 전송에도 안전
SFTP 지원 SFTP를 쉽게 사용 가능하도록 직관적인 API 제공
유연성 SSH 통신 외에도 다양한 설정(포트, 인증)을 커스터마이징 할 수 있어 복잡한 환경에서도 사용 가능
적합성 다른 Python 라이브러리들과 호환성이 뛰어남
활용성 단순 파일 전송뿐 아니라, 원격 서버에서 명령 실행, 파일 목록 가져오기, 정보 검색 등의 작업도 지원

 

 

Paramiko 설치

pip install paramiko

SFTP 구현

1. SFTP 클라이언트 생성 및 반환 함수

- 이 함수는 SFTP 클라이언트를 생성하고 반환합니다. paramiko.Transport 객체를 사용하여 원격 서버와 연결을 설정하며, 연결 정보(host, port, username, password)를 사용하여 SFTP 연결을 초기화합니다.

##SFTP 클라이언트를 생성하고 반환
def create_sftp_client(host, port, username, password):
    try:
        transport = paramiko.Transport((host, port))  # Transport 객체 생성
        transport.connect(username=username, password=password)  # 연결 수행
        return paramiko.SFTPClient.from_transport(transport), transport  # SFTP 클라이언트 반환
    except Exception as e:
        print(f"SFTP 연결에 실패했습니다: {e}")  # 예외 핸들링
        return None, None

 

매개변수 - host : SFTP 서버의 IP 주소 / port : SFTP 서버의 포트 (기본포트: 22) / username, password : SFTP 인증 정보

리턴 - 성공시 : Client, transport 객체 / 실패시 : None, None


2. 원격 서버의 특정 디렉토리에 있는 모든 파일을 로컬 디렉토리로 다운로드하는 함수

# 원격 디렉토리의 모든 파일을 다운로드
def sftp_download_directory(host, port, username, password, remote_directory, local_directory):

    sftp, transport = create_sftp_client(host, port, username, password)  # SFTP 클라이언트 생성
    if not sftp or not transport:
        return  # 연결에 실패하면 함수 종료
    try:
        remote_files = sftp.listdir(remote_directory)  # 원격 디렉토리 내 파일 목록 가져오기
        print(f"원격 디렉토리({remote_directory})의 파일 목록: {remote_files}")
        if not os.path.exists(local_directory):  # 로컬 디렉토리가 없으면 생성
            os.makedirs(local_directory)
        for file_name in remote_files:  # 원격 디렉토리의 파일 반복 처리
            remote_file_path = os.path.join(remote_directory, file_name)
            local_file_path = os.path.join(local_directory, file_name)
            print(f"다운로드 중: {remote_file_path} -> {local_file_path}")
            sftp.get(remote_file_path, local_file_path)  # 파일 다운로드
        print("모든 파일을 성공적으로 다운로드했습니다!")
    except Exception as e:
        print(f"파일 다운로드 중 오류 발생: {e}")  # 예외 처리
    finally:
        # 연결 종료
        if sftp:
            sftp.close()
        if transport:
            transport.close()

동작 과정
     SFTP 연결을 생성하기 위해 create_sftp_client 호출.
     원격 디렉토리(remote_directory) 내 파일 목록을 가져옵니다.
     로컬 디렉토리(local_directory)가 존재하지 않으면 생성.
     원격 디렉토리의 각 파일을 로컬 디렉토리로 다운로드.
     다운로드가 끝나면 SFTP 및 Transport 연결을 닫습니다.


매개변수
     remote_directory: 다운로드하려는 원격 디렉토리 경로
     local_directory: 다운로드받은 파일이 저장될 로컬 경로


3. main 블록

- 스크립트가 독립적으로 실행될 때 실행 가능한 코드를 정의합니다. 여기서는 sftp_download_directory로 서버에 대해 호출합니다.

if __name__ == "__main__":
    host = "xxx.xxx.xx.xxx"
    port = 22
    username = "user"
    password = "password"
    remote_directory = "/home/test"
    local_directory = "D:/test/SFTP/db/"
    # 서버에서 디렉토리 다운로드
    sftp_download_directory(host, port, username, password, remote_directory, local_directory)

 


4. 정리

 

주요 특징

4-1. SFTP를 활용한 파일 관리
- 원격 파일/디렉토리 다운로드


4-2. 오류 처리
- 예외 발생 시 메시지를 출력하여 디버깅 용이


4-3. 재사용 가능한 구조
- create_sftp_client를 통해 SFTP 연결 로직을 분리, 재사용 가능.

 

4-4. 전체 코드 블록

def create_sftp_client(host, port, username, password):
    try:
        transport = paramiko.Transport((host, port))  # Transport 객체 생성
        transport.connect(username=username, password=password)  # 연결 수행
        return paramiko.SFTPClient.from_transport(transport), transport  # SFTP 클라이언트 반환
    except Exception as e:
        print(f"SFTP 연결에 실패했습니다: {e}")  # 예외 핸들링
        return None, None

def sftp_download_directory(host, port, username, password, remote_directory, local_directory):
    sftp, transport = create_sftp_client(host, port, username, password)  # SFTP 클라이언트 생성
    if not sftp or not transport:
        return  # 연결에 실패하면 함수 종료
    try:
        remote_files = sftp.listdir(remote_directory)  # 원격 디렉토리 내 파일 목록 가져오기
        print(f"원격 디렉토리({remote_directory})의 파일 목록: {remote_files}")
        if not os.path.exists(local_directory):  # 로컬 디렉토리가 없으면 생성
            os.makedirs(local_directory)
        for file_name in remote_files:  # 원격 디렉토리의 파일 반복 처리
            remote_file_path = os.path.join(remote_directory, file_name)
            local_file_path = os.path.join(local_directory, file_name)
            print(f"다운로드 중: {remote_file_path} -> {local_file_path}")
            sftp.get(remote_file_path, local_file_path)  # 파일 다운로드
        print("모든 파일을 성공적으로 다운로드했습니다!")
    except Exception as e:
        print(f"파일 다운로드 중 오류 발생: {e}")  # 예외 처리
    finally:
        # 연결 종료
        if sftp:
            sftp.close()
        if transport:
            transport.close()

if __name__ == "__main__":
    host = "xxx.xxx.xx.xxx"
    port = 22
    username = "user"
    password = "password"
    remote_directory = "/home/test/"
    local_directory = "D:/test/SFTP/db/"
    # 서버에서 디렉토리 다운로드
    sftp_download_directory(host, port, username, password, remote_directory, local_directory)

'Python' 카테고리의 다른 글

[Python] tkinter를 활용한 SFTP 자동 실행 구현하기  (0) 2025.03.18