SFTP in Python

Upload, download, read and write files on SFTP servers from Python services.

Your services reach SFTP servers through self.sftp, looking connections up by the name they were given in the Dashboard or in enmasse.

Upload and download

from zato.server.service import Service

class SyncInvoices(Service):

    def handle(self):

        conn = self.sftp['My SFTP']

        # Upload a local file to a remote path
        conn.upload('/local/invoices/2026-08.csv', '/incoming/invoices/2026-08.csv')

        # Download a remote file to a local path
        conn.download_file('/outgoing/reports/summary.csv', '/local/reports/summary.csv')

Read and write remote files directly

No local files are needed - data goes straight between your service and the server:

from zato.server.service import Service

class ExportOrder(Service):

    def handle(self):

        conn = self.sftp['My SFTP']

        data = self.request.raw_request
        conn.write(data, '/incoming/orders/order-4711.json')

        ack = conn.read('/outgoing/acks/order-4711.txt')
        self.response.payload = {'ack': ack}

Guaranteed delivery

.publish spools the data locally and retries until the server accepts it, so the file arrives even if the server is down at the moment of sending:

from zato.server.service import Service

class PublishReport(Service):

    def handle(self):

        conn = self.sftp['My SFTP']
        conn.publish(self.request.raw_request, '/incoming/reports/daily.csv')

List and inspect directories

from zato.server.service import Service

class ListIncoming(Service):

    def handle(self):

        conn = self.sftp['My SFTP']

        for item in conn.list('/incoming/invoices'):
            self.logger.info('%s %s %s', item.name, item.size_human, item.last_modified)

        if conn.exists('/incoming/invoices/2026-08.csv'):
            conn.move('/incoming/invoices/2026-08.csv', '/archive/invoices/2026-08.csv')

Run SFTP commands

Anything the sftp binary understands can be executed as well:

from zato.server.service import Service

class CleanUp(Service):

    def handle(self):

        conn = self.sftp['My SFTP']

        out = conn.execute('rm /incoming/tmp/*.part')
        self.logger.info(out.stdout)

Configuration

The enmasse YAML for the connection:

sftp:
  - name: My SFTP
    address: sftp.example.com:22
    username: zato
    private_key: /keys/id_ed25519
    strict_host_key_checking: true

See also

FeatureWhat it does
Connection APIEvery method of SFTP and SMB connection objects
File transfer schedulesHave Zato watch a remote directory and invoke a service per file
SMBThe same API against Windows shares
SchedulerRun transfers on an interval or at a specific time

Learn more