To define a Chalk Function, decorate a Python callable with @chalkcompute.function:

import chalkcompute

@chalkcompute.function
def add(x: int, y: int) -> int:
    return x + y

if __name__ == "__main__":
    add.wait_ready()
    result = add.remote(3, 5)
    print(result)  # 8

Deploy by running the script: the decorator registers the function with Chalk as soon as it runs. wait_ready() blocks until the deployed function is available, and .remote(...) invokes it. add(3, 5) runs the Python body locally instead; use .remote(...) to call the deployed version.

To call an already-deployed function from a different script — without redeploying — attach to it by name with RemoteFunction.from_name:

import chalkcompute

fn = chalkcompute.RemoteFunction.from_name("add")
result = fn.remote(3, 5)
print(result)  # 8

​
Function dependencies in external files

A deployed function often calls helpers defined in other files. Whether a helper resolves remotely depends on where it lives relative to the decorated function (the function under @chalkcompute.function):

  • Helper in the decorated function’s own package: the function’s entire top-level package is shipped automatically, so imports of sibling modules resolve remotely with no extra configuration.
  • Helper anywhere else (a standalone module, or a different package): must be declared on the image with Image.add_local_python_source. The same applies to all file-external helpers when the decorated function is defined in a standalone script rather than a package.

​
Same package: automatic

If the decorated function’s module runs as part of a package (imported from an entrypoint, or executed directly with python -m), Chalk ships the whole top-level package in the deploy image:

# mypkg/helpers.py
def normalize(text: str) -> str:
    return text.strip().lower()
# mypkg/pipeline.py
import chalkcompute

from mypkg.helpers import normalize

@chalkcompute.function
def clean(text: str) -> str:
    return normalize(text)
# main.py  (outside mypkg/)
from mypkg.pipeline import clean

print(clean.remote("  Hello "))
uv run python main.py

Running the entrypoint (or the function’s own module with uv run python -m mypkg.pipeline) deploys clean with all of mypkg, so normalize is importable remotely exactly as it is locally.

Running the file by path (uv run python mypkg/pipeline.py) ships only that one file because Python doesn’t know that it belongs to a package. In this scenario, Chalk will raise an error at deploy time.

Every run of an entrypoint that imports the decorated function deploys a new function version. To call an existing deployment without redeploying, attach to it by name with RemoteFunction.from_name instead.

# call_clean.py: call the deployed function without triggering a redeploy
import chalkcompute

fn = chalkcompute.RemoteFunction.from_name("clean")
print(fn.remote("  Hello "))
uv run python call_clean.py

​
Everything else: add_local_python_source

When the decorated function is defined in a standalone script, or imports helpers from outside its own top-level package, list those local modules or packages on the image:

# helpers.py  (next to deploy.py)
def normalize(text: str) -> str:
    return text.strip().lower()
# deploy.py
import chalkcompute

from helpers import normalize

@chalkcompute.function(
    image=chalkcompute.Image.debian_slim().add_local_python_source("helpers"),
)
def clean(text: str) -> str:
    return normalize(text)
uv run python deploy.py

add_local_python_source accepts any number of top-level module or package names. Each must be importable on your local Python path; packages are copied whole (excluding __pycache__). Dotted names, namespace packages spanning multiple directories, and compiled extensions are rejected with a ValueError.

This ships your own source code only. Third-party dependencies still need to be installed in the image with pip_install or run_commands.