# 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 ```python 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 ```python 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 {ref}`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. --- ## Related settings Upload behavior is affected by: * {ref}`EDRI_UPLOAD_FILES_PATH ` * {ref}`EDRI_UPLOAD_FILES_PREFIX ` * {ref}`EDRI_MAX_FILE_SIZE ` See {doc}`/env` for details.