Docs

Inputs

How type hints become form fields: text, numbers, dropdowns, dates, lists, models and file uploads.

A function's parameters become its form. The type hint picks the field, the default prefills it, and the parameter name becomes the label.

from datetime import date
from typing import Literal

from callables import deploy


@deploy(title="Closed deals")
def closed_deals(
    region: Literal["NA", "EMEA", "APAC"] = "NA",
    since: date | None = None,
    min_value: int = 0,
    include_refunds: bool = False,
) -> list[dict]: ...

This form has a dropdown, an optional date picker, a number field and a checkbox.

Type hints and fields

Type hintForm field
strText box
int, floatNumber
boolCheckbox
date, datetimeDate or date-time picker
Literal["a", "b"] or an EnumDropdown
list[str], list[int] and so onList editor
X | None = NoneOptional field
A Pydantic modelGrouped sub-form
File, or Annotated[File, accept(".csv")]File upload

Required and optional

  • A parameter without a default is required.
  • A default makes the field optional and prefills it.
  • X | None = None is an optional field that starts empty.

Labels

Parameter names become labels: min_value shows as "Min value". Choose names that read well to the people running the function.

Validation

Inputs are validated and converted before your function runs, the same way in the web app, from the CLI and in call local. A date arrives as a datetime.date, an Enum as its member and a model as an instance. Invalid input is shown next to its field, and the function isn't called.

Models

Group related fields with a Pydantic model:

from pydantic import BaseModel

from callables import deploy


class Address(BaseModel):
    street: str
    city: str
    postcode: str


@deploy(title="Update shipping address")
def update_address(order_id: str, address: Address) -> str: ...

Good practice

  • Prefer Literal[...] over free text whenever the valid values are known.
  • Avoid dict inputs: they show as a raw JSON box. Use a Pydantic model instead.
  • Never take an API key or password as an input. Declare it as a secret.

Not supported

*args, **kwargs, Callable and arbitrary classes. call check names any parameter it can't turn into a field.

For file uploads, see files.