Deploy from a monorepo or subfolder, with system packages
Callables builds your repo the way you already set it up. Most projects need nothing extra. This guide covers the settings for everything else: automations in a subfolder, a specific Python version, and command-line tools your code shells out to.
Dependencies
Callables installs your Python dependencies from requirements.txt at the repo root, or from [project].dependencies in pyproject.toml if there's no requirements.txt.
Don't list callables itself. The platform installs its own copy, matched to the server.
Python version
The version comes from, in order:
- A
.python-versionfile, like3.13. - Otherwise, the newest version your
pyproject.tomlrequires-pythonallows. - Otherwise, Python 3.12.
Python 3.11 to 3.14 are supported.
Automations in a subfolder
By default, the whole repo is built. If your automations live in one folder of a bigger repo, add a callables.toml at the repo root:
root = "automations"
Or put the same setting in pyproject.toml:
[tool.callables]
root = "automations"
Then only that folder is built, and its own requirements.txt, apt.txt and .python-version are used. Code inside it can't import from the rest of the repo, so keep shared helpers inside the folder. call check and call local use the same folder when you run them from the repo root.
System packages with apt.txt
When a function shells out to a command-line tool, like a converter, a database client or a headless browser, list the Debian packages it needs in apt.txt:
# apt.txt: one package per line
ffmpeg
poppler-utils
postgresql-client
- Names only, no versions. You get the version Debian 13 ships.
- Packages are installed without their "recommended" extras. If a tool is missing something, like fonts, list that package too.
- They're installed once each time
apt.txtchanges, not on every push. call localuses the tools on your own machine, so install them there too.
The runtime
A few things to know about where your code runs:
- Your code is read-only. Write temporary files to
/tmp(up to 256 MB) or your home directory. - Every run starts fresh. Nothing persists between runs, so keep state in your own database or storage.
- Downloaded binaries can't run from
/tmp. Put them in your home directory and make them executable, or better, install the tool withapt.txt. - Memory and CPU go up to your plan's limit, and you're billed for what the run actually uses. Each run's page shows its peak memory and CPU time.
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.