PYTHON – praca z serwerami FTP i SFTP

W codziennej pracy analityka, regularnie możemy spotkać się z sytuacjami, w której musimy przesłać przygotowane przez nas dane do np. firmy zewnętrznej z wykorzystaniem serwerów ftp i sftp. Poniższy artykuł jest poświęcony wymianie plików za pośrednictwem tych serwerów.

FTP

Pobieramy najnowszy plik z określonej lokalizacji na serwerze

Import bibliotek:

import sys
import ftplib
import os
from ftplib import FTP

Wpisujemy dane do zalogowania się na serwer:

ftp=FTP("nazwa hosta")
ftp.login("login","hasło")

Zmieniamy katalog roboczy (z którego będziemy pobierać pliki):

path=source="xxx/yyy/"
ftp.cwd(path)

Tworzymy listę wszystkich plików z katalogu i wybieramy ten z najnowszą datą modyfikacji:

entries = list(ftp.mlsd())
entries.sort(key = lambda entry: entry[1]['modify'], reverse = True)
latest_name = entries[0][0]

Pobieramy plik z ftp i wrzucamy do określonej przez nas lokalizacji na komputerze:

with open(os.path.join('sciezka_lokalna/',latest_name),"wb") as f:
ftp.retrbinary("RETR "+latest_name, f.write)

Opcjonalnie zmieniamy nazwę naszego pobranego pliku:

poprzednia_nazwa = 'sciezka' + latest_name+'.csv'
obecna = 'sciezka/nowa_nazwa.csv'
os.rename(poprzednia_nazwa, obecna)

Wrzucamy plik z lokalnego komputera na serwer FTP

import ftplib

Wpisujemy dane serwera i łączymy się:

ftpHost=’xxxxxx.xxxx’

ftpPort=’xx’

ftpUname=’xxxx’

ftpPass=’xxxx’

ftp=ftplib.FTP()

ftp.connect(ftpHost,ftpPort)

ftp.login(ftpUname,ftpPass)

try:

    ftp.cwd('sciezka_na_ftp') – ustawiamy katalog roboczy na serwerze do którego chcemy

skopiować plik

    localFilePath = “C:Users/sciezka_z_plikiem/plik.xlsx" – wpisujemy pełną ścieżkę lokalnego

pliku

    path="STOR " + "plik.xlsx" – wpisujemy polecenie „STOR „ oraz nazwę pliku z rozszerzeniem (bez

ścieżki)

    with open (localFilePath,'rb') as file: – otwieramy lokalny plik do odczytu

              ftp.storbinary(path,file) – i wstawiamy na serwer

except:

    print('failed to establish connection to targeted server')

SFTP

Wrzucamy plik na serwer SFTP

import pysftp

try:

    with pysftp.Connection(host="xxxxxx ",  username=”xxxx”, password=("xxx "), port=xx) as

sftp: - łączymy się z serwerem

       sftp.cwd('sciezka_na_ftp) – zmieniamy katalog roboczy

       sftp.put(“C:Users/sciezk_z_lokalnym_plikiem/plik.xlsx”) – wstawiamy plik

except:

    print('failed to establish connection to targeted server')

W przypadku błędu: 'Connection’ object has no attribute '_sftp_live’ możemy użyć następującego kodu (który jednak zdejmuje zabezpieczenia na połączeniu):

cnopts = pysftp.CnOpts()

cnopts.hostkeys = None

try:

    with pysftp.Connection(host="xxxxxx ",  username=”xxxx”, password=("xxx "), port=xx,

cnopts=cnopts) as sftp:

       sftp.cwd('sciezka_na_ftp)

       sftp.put(“C:Users/sciezk_z_lokalnym_plikiem/plik.xlsx”)

except:

    print('failed to establish connection to targeted server')

Pobieranie plików z SFTP

Business Case:

Musimy pobrać wszystkie pliki z danej lokalizacji na SFTP, z „IMPORTED” w nazwie:

import pysftp

try:

  conn = pysftp.Connection(host="xxxxxx ",  username=”xxxx”, password=("xxx "), port=xx)

  print("connection established successfully")

except:

  print('failed to establish connection to targeted server')

with conn.cd(‘SCIEZKA_NA_FTP'):

    files = conn.listdir()

lista=[]

for element in files:

    if 'IMPORTED’ in element:

        lista.append(element)

ile=len(lista)

with conn as sftp:

    for el in range (0,ile,1):

        remoteFilePath = 'sciezka_sftp'+str(lista[el])

        localFilePath = 'sciezka_lokalna'+str(lista[el])

        plik.append(localFilePath)

        sftp.get(remoteFilePath, localFilePath)