Skip to main content

SFTP automation in Python.

Automate partner file drops with streaming, retries, and credentials that never touch your code.

You are maintaining an SFTP script.

You have a Python script on a server, a cron keeping it on schedule, and credentials stored somewhere you hope nobody forgets to update. The nightly import pulls 200 files from your partner's server. When the connection drops on file 143, there is no checkpoint, so tomorrow starts at file 1. Your partner rotates their key quarterly and you find out when Monday's data is missing. The 3 GB transaction file exceeds your Lambda's memory and crashes before logging what happened.

transfer.py
import paramiko
import os

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(
    os.environ["SFTP_HOST"],
    username=os.environ["SFTP_USER"],
    password=os.environ["SFTP_PASS"],
)
sftp = ssh.open_sftp()

for filename in sftp.listdir("/incoming"):
    sftp.get(f"/incoming/{filename}", f"/tmp/{filename}")
    process_file(f"/tmp/{filename}")

    qbash Tasks.

    A Task is an AI automation written in Python, hosted on a managed runtime. A developer writes the script; anyone runs it from a form. Integrations, model calls, version control, and logging are built in.

    Model and provider agnostic.

    • Anthropic
    • OpenAI
    • Gemini
    • xAI
    • OpenRouter
    • Amazon
    • Perplexity
    • MoonshotAI
    • Meta
    • Qwen

    Instead, write it as a qbash Task.

    A qbash Task is a Python script that runs on a managed runtime. You write the same code you would write in paramiko — connect, list, download, process — and the platform handles the server, the schedule, the credentials, and the retries. Transfers stream up to 5 GB and resume from where they dropped. After the download, the same script can classify files with a model and post results to Slack or email. Every run is logged with what transferred and what failed.

      partner-drop.py
      files = qbash.integrations.sftp.list_files("/incoming")
      
      for f in files:
          data = qbash.integrations.sftp.read_chunk(
              f["path"], start_row=0, num_rows=5000,
          )
          summary = qbash.ai.run_prompt(
              slug="process-partner-data",
              variables={"rows": data, "filename": f["name"]},
          )
          qbash.integrations.slack.create_message(
              "#partner-data",
              text=f"{f['name']}: {summary['report']}",
          )

      What happens after the file lands.

      Chunked file processing

      read_chunk and read_lines let you iterate through a large CSV or line-based file without loading it all into memory. A checkpoint tracks which rows have been processed, so a restart picks up where it left off instead of reprocessing from the beginning.

      chunk.py
      rows = qbash.integrations.sftp.read_chunk(
          "/incoming/transactions.csv",
          start_row=0, num_rows=1000,
      )
      
      results = qbash.parallel(
          process_row, rows,
          concurrency=5,
          checkpoint="txn-import",
          retry=3,
      )

      AI-powered extraction

      Run a model over each file to classify it, extract structured fields, or generate a summary. output_schema constrains the response to your JSON shape, so downstream code reads typed fields instead of parsing free text.

      extract.py
      invoice = qbash.ai.run_prompt(
          slug="extract-invoice-fields",
          variables={"text": file_content},
          output_schema={
              "type": "object",
              "properties": {
                  "vendor": {"type": "string"},
                  "amount": {"type": "number"},
                  "due_date": {"type": "string"},
              },
          },
      )

      Run it from ChatGPT or Claude

      Connect qbash as an MCP server and the SFTP task becomes a tool anyone on the team can call from ChatGPT, Claude, or Cursor. Typed inputs like remote path and file pattern become parameters the chat fills in. Credentials stay server-side, so the person running the task never sees them.

      mcp
      Connect qbash as an MCP server
      in ChatGPT, Claude Code, or Cursor.
      
      The SFTP task becomes a callable tool.
      
      "Pull the latest files from /incoming
      and summarize them" triggers the task
      from your AI chat.

      Questions

      How large a file can qbash download over SFTP?

      Up to 5 GB per file. Downloads are streaming and checkpoint-resumable, so a retry picks up where it left off rather than re-downloading from the start.

      Does qbash support FTP as well as SFTP?

      Yes. The SFTP/FTP integration supports both protocols. The same methods (list_files, read_chunk, download_file) work for either.

      How are SFTP credentials handled?

      Connect the SFTP server once at the org level. Credentials are brokered server-side, never in your code, environment variables, or logs. Rotation is a credential update in qbash, not a redeploy of every script.

      Can I test the SFTP logic without hitting a real server?

      Yes. testing.mock_sftp() provides a mock SFTP client for tests.py. Assert that the processing logic works without making a real connection.

      Is this an enterprise MFT platform?

      No. If you need HIPAA/GLBA compliance, partner onboarding portals, and multi-protocol EDI orchestration, Kiteworks, GoAnywhere, or Couchdrop are built for that. qbash is for developers automating partner file drops in Python, with a managed runtime and built-in integrations.

      Competitor details reviewed . Vendors change plans and features without notice, so check theirs before deciding.

      Ship your first task.

      Connect your SFTP server, write the processing script, and put it on a schedule. Every transfer logged, every file processed inline.