Uploads

EDRI stores uploaded files as filesystem-backed temporary files and passes them to event handlers as File objects.

Uploaded files are created with delete=False. EDRI does not automatically delete uploaded files after request processing, response sending, manager handling, or worker handling.

This is intentional. Events may be processed asynchronously, queued, retried, forwarded to workers, or handled outside the API listener lifecycle. The framework cannot reliably know when application code is done with an uploaded file.


Lifecycle responsibility

Application code is responsible for managing uploaded files.

After receiving a File, the application should explicitly do one of the following:

  • move it to permanent storage,

  • copy it elsewhere,

  • delete it after processing,

  • or rely on an application or operating-system cleanup policy for EDRI_UPLOAD_FILES_PATH.

Example: move to permanent storage

from pathlib import Path
from shutil import move


def handle_upload(event):
    upload = event.file

    permanent_path = Path("/var/lib/my-app/uploads") / upload.file_name
    move(upload.path, permanent_path)

    event.response.path = str(permanent_path)

Example: process and delete

from pathlib import Path


def handle_upload(event):
    upload_path = Path(event.file.path)

    try:
        with upload_path.open("rb") as uploaded_file:
            process(uploaded_file)
    finally:
        upload_path.unlink(missing_ok=True)

Workers

When uploaded files are processed by workers, File.path must be accessible to the worker process.

For local workers this usually means that the upload directory is on the same filesystem. For containerized or remote workers, use a shared volume or move the file to application-managed shared storage before dispatching work.

EDRI does not delete uploaded files when a worker finishes or exits. Worker completion does not necessarily mean the application no longer needs the file.

Streaming an upload (no temporary file)

The notes above assume File.path is a Path on disk — the default, where the body is fully buffered before the event is dispatched. For a file-only event uploaded with Expect: 100-continue, EDRI instead streams the body to the Worker through a SharedMemoryPipe: File.path is a pipe reader, the event is dispatched immediately, and the Worker consumes the file as it arrives — no temporary file, constant memory, with HTTP receive throttled by how fast the Worker reads. See The other direction: reading an upload as it arrives.


Production checklist

For production deployments:

  • set EDRI_UPLOAD_FILES_PATH to a dedicated directory,

  • do not use a shared system-wide temp directory for untrusted uploads,

  • put filesystem quotas or container volume limits on the upload directory,

  • configure OS-level cleanup if your application does not delete files itself,

  • ensure worker processes can access EDRI_UPLOAD_FILES_PATH,

  • ensure application code deletes or moves files after processing.