Let teammates upload a file and get a result back
A lot of internal work is "here's a file, please fix it": a contact list full of duplicates, an export that needs reformatting, a batch of PDFs to merge. With Callables, a function can take a file upload and hand back a download, so teammates can do it themselves.
Take a file as input
Use File as a parameter type to get an upload field, and accept(...) to limit the file types:
from typing import Annotated
from callables import File, accept, deploy
@deploy(title="Clean up a contact list")
def clean_contacts(sheet: Annotated[File, accept(".csv")]) -> File:
"""Removes duplicate rows and fixes capitalization."""
rows = sheet.read_text().splitlines()
...
out = "/tmp/clean.csv"
... # write the cleaned rows to out
return File(out, name=f"clean-{sheet.name}")
Your teammate sees an upload field that only accepts CSV files. Inside the function, the upload has what you'd expect:
sheet.read_text()andsheet.read_bytes()for the contentssheet.open()for a file object, andsheet.pathfor its path on disksheet.nameandsheet.size
Return a file to download
Returning a File gives the person a download button. Return list[File] for several downloads.
To add downloads next to another result, use save_file. This function shows a summary and also offers the cleaned file:
from callables import File, accept, deploy, save_file
@deploy(title="Clean up a contact list")
def clean_contacts(sheet: Annotated[File, accept(".csv")]) -> str:
...
save_file(out, name=f"clean-{sheet.name}")
return f"Removed **{removed}** duplicates from {total} rows."
save_file also takes bytes, with a name.
Try it locally
Pass a file with @ and the path:
call local clean_contacts -i [email protected]
Outputs land in ./callables-output/, so you can check them before you push.
Limits to know
- Uploads can be up to 100 MB.
- A run can produce up to 100 MB and 20 files of output.
- Files are deleted after 24 hours, so people should download what they need.
- Functions with file inputs can't be scheduled, since nobody is there to pick the file.
- Write temporary files to
/tmp(up to 256 MB) or your home directory. Each run starts fresh.
Ideas
- Merge or split PDFs.
- Convert a supplier's spreadsheet into your import format.
- Check a CSV against your database and return the rows that don't match.
- Resize a folder of images uploaded as a zip.
Turn your scripts into tools your team can run
Add @deploy to a Python function and push. Your team gets a form, schedules and run history.