A file transfer pipeline you can actually fail closed
Files land in an inbox. Some are empty. Some are the same file dropped twice. Some look fine until SFTP is down. This lab is a sanitized stand-in for the managed file transfer work I do — landing zone, validate, transform, deliver, audit.
Production MFT is not a happy-path script. Partners drop CSV, JSON, and HL7 into a landing zone. A worker has to decide, every time: is this file real, is it a duplicate, and did delivery actually succeed? If any of those answers is no, the original stays put and the failure is recorded — not swallowed by a retry that nobody can reconstruct later.
file-transfer-pipeline is that shape without client data or vendor lock-in. Terraform stands up a local Docker landing zone (and an AWS S3 sketch). Python does the rest.
The path a file takes
Every inbound file goes through the same five steps:
- Land in
data/inbox/(or an S3 prefix in the AWS sketch). - Validate size, encoding, and format. HL7 gets a fast MSH gate here; deeper parsing lives in the companion HL7 toolkit.
- Transform a good file into a canonical JSON payload.
- Deliver to a local sink or SFTP.
- Audit the attempt in SQLite, including SHA-256 so the same content is not delivered twice.
What I wanted to show failing
The interesting cases are the ones that turn into tickets at 2 a.m. if you only test the green path:
| Failure | What the pipeline does |
|---|---|
| Empty or huge file | Reject with a stable error code |
| Bad encoding / invalid JSON / header-only CSV | Quarantine plus a .error.json sidecar |
| HL7 without MSH-9 or MSH-10 | Reject before delivery |
| Same content dropped twice | Skip via SHA-256 audit key |
| Downstream SFTP outage | Keep the original in failed/ and record the error |
Infra as code, not a console screenshot
I used Terraform at work, so the lab does too.
infra/local uses the Docker provider to bring up SFTP and Postgres.
infra/aws sketches S3 inbox / processed / failed buckets plus IAM — CI runs
terraform validate; you should not apply it without a backend and an account.
cd infra/local
terraform init
terraform plan
Run it
python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
cp samples/partners.csv data/inbox/
file-pipeline --root data
pytest -q
After docker compose up -d or terraform apply in infra/local:
file-pipeline --root data --sftp
What this is not
It is not a MOVEit or GoAnywhere clone, and it is not production. It is the interviewable version of the job: a worker that fails closed, leaves an audit trail, and treats landing zones as code. The HL7 companion post covers the parser that explains why a message is bad after this pipeline’s MSH gate.