Docs

Files

Take file uploads, return files to download, and save extra files from a run.

Functions can take file uploads, return files to download, and save extra files alongside any result.

from typing import Annotated

from callables import File, accept, deploy, save_file


@deploy(title="Clean up a contact list")
def clean_contacts(sheet: Annotated[File, accept(".csv")]) -> File:
    """Removes duplicate rows and fixes capitalisation."""
    rows = sheet.read_text().splitlines()
    save_file(f"{len(rows)} rows in".encode(), name="summary.txt")
    out = "/tmp/clean.csv"
    ...
    return File(out, name=f"clean-{sheet.name}")

Uploads

A File parameter becomes an upload field. Use Annotated[File, accept(".csv", ".xlsx")] to limit the file types. Your function gets a File with:

  • .path: where the file is on disk
  • .name: the original file name
  • .size: its size in bytes
  • .read_text() and .read_bytes(): its contents
  • .open(): a file object, like the built-in open()

Downloads

Return a File, or a list[File], and the person gets download buttons. File(path, name=...) sets the name they download it as.

Extra files

save_file(path_or_bytes, name=...) adds a download alongside any return value, such as a table plus the spreadsheet it came from. It needs name= when you pass bytes.

Locally

Pass a file to call local with @. Outputs land in ./callables-output/, which call init adds to .gitignore.

call local clean_contacts -i [email protected]

Limits

  • 100 MB per upload.
  • 100 MB and 20 files of output per run.
  • Files are deleted after 24 hours.
  • Functions with file inputs can't be scheduled, since nobody is there to pick the file.

Write temporary files under /tmp (up to 256 MB) or your home directory. See builds and runtime.