Skip to main content

context.work_dir

A per-run scratch directory you can write to.

context.work_dir # → str, absolute path
import os

path = os.path.join(context.work_dir, 'export.csv')
with open(path, 'w', encoding='utf-8') as f:
f.write('header1,header2\n')
f.write('value1,value2\n')
context.logger.info(f"Wrote export to {path}")

Created lazily on first access. If you never touch context.work_dir, no directory is created.

What it's actually pointing at​

EnvironmentPathLifecycle
Production/tmp/connector_run/<entrypoint_key>_<YYYYMMDD-HHMMSS-fff>/ inside the Docker containerWiped when the container exits at end of job
Toolkit<repo>/temp_work/<entrypoint_key>_<YYYYMMDD-HHMMSS-fff>/Persists between runs so you can inspect what your entrypoint produced; each run gets its own timestamped subdirectory

In both environments the path is isolated per entrypoint: two entrypoints running side-by-side don't see each other's files.

What to use it for​

Good fitWhy
Attachment downloads: att.save(name) writes here by defaultLives only as long as the run needs it
CSV / Excel exports you're about to SFTP pushBuild → push → forget
Intermediate files during parsing: split a multi-invoice PDFCleaned up automatically
Debug dumps: write the raw external payload before you transform itToolkit keeps it; production discards it

What NOT to use it for​

Don't treat it as durable storage​

It's gone the moment the container exits. If you need anything to survive across runs, write it to:

  • Nuntiq (via context.api: entity Loads, custom data tables, lifecycle messages).
  • An external system (SFTP push, S3 put, ERP API).
  • The structured log (small observability metadata only).

Don't escape the directory​

work_dir is a single absolute path. Don't construct paths with ../ or absolute paths that point outside it. The framework rejects escapes by asserting paths stay inside work_dir, but the cleanest pattern is to always use os.path.join(context.work_dir, name).

# ❌
path = '/tmp/something.csv' # outside work_dir
path = os.path.join(context.work_dir, '../foo') # escapes

# ✅
path = os.path.join(context.work_dir, 'something.csv')

Don't shell-out and cd somewhere else​

Subprocess calls inherit the container's working directory, which is /tmp/job/: not context.work_dir. If you shell out (e.g. to gpg or ffmpeg), pass absolute paths.

Attachments: the common case​

Every attachment you pull off an invoice already knows about context, so calling att.save(filename) writes into context.work_dir without extra plumbing:

for att in invoice.attachments:
local_path = att.save(att.file_name) # writes to context.work_dir
context.logger.info(f"Saved {att.file_name} to {local_path}")

# Or just read into memory:
data = att.read_bytes()
text = att.read_base64()

See Invoice claim flow for the full pattern, and SFTP push for a real example that builds files in work_dir, uploads them, and lets the cleanup happen on container exit.