# Python SDK

> Install the callables package, and everything it exports: deploy, Group, Next, Connection, Secret, Ask, File and the call command.

Source: https://callables.app/docs/sdk

The Python SDK is the `callables` package. It holds everything you write functions with (`@deploy`, groups, connections, files), and it installs the `call` command you check and run them with. This page lists everything it exports, with links to the pages that cover each one in depth.

## Install

```bash
pip install callables
```

It needs Python 3.11 or newer, and its only dependency is [Pydantic](https://docs.pydantic.dev) 2. Keep it out of your project's `requirements.txt`: builds install the platform's own copy (see [versions](#versions)). Then run `call init` in the repo to add a starter function and the guide for coding agents (see the [quickstart](https://callables.app/docs/quickstart)).

The source is on GitHub at [callables-app/callables-python](https://github.com/callables-app/callables-python), and releases are on [PyPI](https://pypi.org/project/callables/). Run `call docs` to print the full guide to writing functions, the same text `call init` gives your coding agent.

## What it exports

```python
from callables import deploy, command, Group, Next, Connection, Secret, Ask, File, accept, save_file
```

| Name | What it's for | More |
|---|---|---|
| `deploy` | Turns a function into a callable: a web form, a CLI command, schedules and run history | [@deploy](https://callables.app/docs/deploy) |
| `Group` | Groups related functions, with shared secrets and connections | [Groups](https://callables.app/docs/groups) |
| `command` | A local-only CLI command, never deployed | [Groups](https://callables.app/docs/groups) |
| `Next` | A next action offered on each result row | [Flows](https://callables.app/docs/flows) |
| `Connection` | An account each person connects themselves, such as their Gmail | [Connections](https://callables.app/docs/connections) |
| `Secret`, `Ask` | Values a connection reads from secrets, or asks each person for | [Connections](https://callables.app/docs/connections#secrets-and-values) |
| `File`, `accept` | File uploads and files to download | [Files](https://callables.app/docs/files) |
| `save_file` | Saves extra files from a run, for download | [Files](https://callables.app/docs/files) |

## deploy

```python
@deploy(
    name=None,         # identity on the platform; defaults to the function name
    title=None,        # the heading people see; defaults to the name as a sentence
    description=None,  # one line on the card; defaults to the docstring's first paragraph
    secrets=None,      # environment variable names, set in the web app
    connections=None,  # Connection objects
    schedule=None,     # a cron expression in UTC; usually set in the web app instead
    timeout=300,       # seconds, up to 900
    next=None,         # next actions: functions, their names, or Next(...)
)
```

Use it bare (`@deploy`) or with options. Type hints become the form's fields ([inputs](https://callables.app/docs/inputs)), and the return type picks how the result is shown ([results](https://callables.app/docs/results)). Every option is covered in [the @deploy decorator](https://callables.app/docs/deploy).

## Group and command

```python
Group(name, *, title=None, description="", secrets=None, connections=None)
```

`@group.deploy(...)` takes the same options as `@deploy`, and the function's full name becomes `group.function`. `@command` and `@group.command` make a CLI command for your own machine that never deploys: `call <group> <command> --flags`. See [groups and local commands](https://callables.app/docs/groups).

## Next

```python
Next(action, label=None, **inputs)
```

`action` is a deployed function or its name. Each keyword maps one of the action's inputs to a field in the result row: `Next(set_plan, label="Change plan", user_id="id")`. See [flows](https://callables.app/docs/flows).

## Connection, Secret and Ask

```python
Connection(
    name,
    *,
    provider=None,       # a preset: "google", "microsoft", "slack", "github", "notion"
    scopes=None,
    client_id=None,      # Secret(...); defaults to Secret("<NAME>_CLIENT_ID")
    client_secret=None,  # Secret(...); defaults to Secret("<NAME>_CLIENT_SECRET")
    values=None,         # fills {placeholders} in the URLs: Secret(...), Ask(...) or plain text
    # For a service without a preset:
    authorize_url=None, token_url=None, authorize_params=None, userinfo_url=None, account_field=None, revoke_url=None,
    # ...plus advanced token-request options, covered in the connections docs
)

Secret(name, default=None)  # a project secret on Callables; an environment variable or .env locally
Ask(prompt)                 # a value each person types when they connect, such as their store name
```

Inside a function, read the connection's attributes:

| Attribute | What it is |
|---|---|
| `conn.token` | An access token for the person running the function, valid for the whole run |
| `conn.account` | The account they connected, such as alice@company.com, when the service says |
| `conn.scopes_granted` | The scopes they granted |
| `conn.extra` | Other values the service returned at sign-in, such as Salesforce's `instance_url` |

Every preset, option and example is in [connections](https://callables.app/docs/connections). Step-by-step setup for each service is on the [connectors page](https://callables.app/connectors).

## File, accept and save_file

```python
File(path, name=None, content_type=None)
accept(*extensions)                             # Annotated[File, accept(".csv", ".xlsx")]
save_file(source, name=None, content_type=None) # source is a path, a File, or bytes (then name is required)
```

A `File` parameter becomes an upload field. Return a `File` (or a list of them) to give people download buttons. A `File` has `path`, `name`, `content_type` and `size`, plus `read_bytes()`, `read_text()` and `open()`. See [files](https://callables.app/docs/files).

## The call command

| Command | What it does |
|---|---|
| `call check` | Lists every problem a deploy would hit, with a fix for each |
| `call local <group> <function> --flags` | Runs a function on your machine. With no name, it lists them |
| `call <group> <function> --flags` | The same, as its own CLI command |
| `call connect [name]` | Signs in to a connection's service, so local runs use your account. With no name, it shows a menu |
| `call disconnect [name]` | Forgets this machine's tokens for a connection |
| `call manifest` | Prints the JSON manifest of every function |
| `call docs` | Prints the guide to writing functions |
| `call init` | Adds a starter function and coding-agent instructions to the repo |

Every flag and option is in the [CLI reference](https://callables.app/docs/cli).

## Versions

The SDK follows [semantic versioning](https://semver.org), and release notes are on [PyPI](https://pypi.org/project/callables/#history). Deploys always run the platform's own copy of the SDK, which is kept current, so a new feature works on Callables as soon as it's released. Locally, `pip install -U callables` gets the latest version for `call check` and `call local`.
