Workflows
Run arbitrary Python scripts in your Chalk deployment
Tasks let you run arbitrary Python code in your Chalk deployment environment with full access to your resolvers, dependencies, and infrastructure.
Tasks execute in the same environment as your resolvers, making them ideal for:
All tasks are tracked and monitored through the Chalk dashboard with full logs, metrics, and status tracking.
The fastest way to run a task is using the Chalk CLI.
First, create a simple Python script:
echo 'print("Hello from Chalk tasks!")' > script.pyThen, run it with the Chalk CLI:
chalk task run script.pyThe CLI will output a link to view your task in the dashboard:
✓ View task at: https://chalk.ai/projects/my-project/environments/prod/tasks/550e8400...
Click the link to see your script’s output, status, and execution metrics.
The chalk task run command executes Python scripts in your deployment:
chalk task run [target] [flags]The target supports multiple formats:
Execute an entire Python script:
chalk task run scripts/data_migration.pyExecute a specific function from a file:
chalk task run scripts/backfill.py::process_batchFor installed Python modules, use the -m / --module flag. Modules require --branch for access to your deployment. See Branch Execution for details.
# Module execution
chalk task run -m mypackage.scripts.backfill --branch my-branch
# Module function
chalk task run -m mypackage.scripts.backfill::main --branch my-branchCLI arguments are always passed as strings. Your function should handle type conversion as needed.
When running a specific function (with ::function), arguments are passed directly to your function as *args and **kwargs:
chalk task run script.py::backfill --arg 2024-01-01 --arg 2024-12-31 --arg dry_run=truedef backfill(start_date: str, end_date: str, dry_run: str = "false"):
"""
Positional arguments: start_date, end_date
Keyword arguments: dry_run
"""
is_dry_run = dry_run == "true"
print(f"Backfilling from {start_date} to {end_date} (dry_run={is_dry_run})")
if not is_dry_run:
# Perform actual backfill
passWhen running a whole file (without ::function), arguments are passed as command-line arguments. You can use sys.argv or an argument parser to access them:
Using sys.argv:
Direct access to raw command-line arguments as a list:
chalk task run script.py --arg 2024-01-01 --arg 2024-12-31#!/usr/bin/env python3
import sys
if len(sys.argv) >= 3:
start_date = sys.argv[1]
end_date = sys.argv[2]
print(f"Processing data from {start_date} to {end_date}")Using argparse:
Provides automatic parsing, help messages, and type handling:
chalk task run process.py --arg users.csv --arg --dry-run --arg output_dir=./results#!/usr/bin/env python3
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('input_file', help='Input CSV file')
parser.add_argument('--dry-run', action='store_true', help='Run without making changes')
parser.add_argument('--output_dir', default='./output', help='Output directory')
args = parser.parse_args()
print(f"Processing {args.input_file}")
print(f"Dry run: {args.dry_run}")
print(f"Output directory: {args.output_dir}")Execute the same script multiple times with different parameters using a JSONL file. This is useful for hyperparameter sweeps, batch processing, or running experiments across different data segments.
Each line is a JSON object with kwargs (and optionally args):
{"kwargs": {"learning_rate": "0.001", "batch_size": "32", "epochs": "10"}}
{"kwargs": {"learning_rate": "0.005", "batch_size": "64", "epochs": "10"}}
{"kwargs": {"learning_rate": "0.01", "batch_size": "128", "epochs": "5"}}chalk task run scripts/train_model.py::train --args-file hyperparams.jsonlThis creates a separate task for each line in the file. The CLI will show progress and provide a link to view all tasks in the dashboard.
From Python:
import json
params = [
{"kwargs": {"user_id": i, "region": "us-west"}}
for i in range(1000, 2000)
]
with open("batch_params.jsonl", "w") as f:
for param in params:
f.write(json.dumps(param) + "\n")From a database query:
import json
import psycopg2
conn = psycopg2.connect(...)
cursor = conn.cursor()
cursor.execute("SELECT user_id, region FROM users WHERE needs_backfill = true")
with open("users_to_backfill.jsonl", "w") as f:
for user_id, region in cursor:
f.write(json.dumps({
"kwargs": {"user_id": user_id, "region": region}
}) + "\n")When you’re making changes across multiple files, updating dependencies, or modifying resolvers that your script uses, it’s important to test everything together before merging to production. Branch deployments let you run tasks in an isolated environment that includes all your changes:
chalk task run scripts.py --branch feature/new-algorithmThis automatically:
chalk apply --branch feature/new-algorithmYou can skip the automatic apply if the branch is already deployed:
chalk task run scripts/hello.py --branch feature/new-algorithm --skip-applySee Working with Branches for more information.
-m, --module - Treat the target as a module import path instead of a file path.
chalk task run -m mypackage.analytics.report--branch BRANCH_NAME - Execute code from a specific git branch. See Branch Execution.
--skip-apply - Skip the automatic chalk apply when running with --branch. Use this if the branch is already deployed.
--arg KEY=VALUE or --arg VALUE - Pass arguments to your script. Can be specified multiple times. See Passing Arguments.
--args-file FILE.jsonl - Execute script multiple times with different arguments from a JSONL file. See Batch Execution.
--max-retries N - Set number of retry attempts on failure. Defaults to 0 (no retries).
chalk task run flaky_api_call.py --max-retries 3Tasks appear in the Chalk dashboard where you can monitor their execution and debug failures.
After submitting a task, the CLI outputs a link to the dashboard:
$ chalk task run scripts/hello.py
✓ View task at: https://chalk.ai/projects/my-project/environments/prod/tasks/550e8400...You can also view all tasks at the tasks overview page, which shows aggregate CPU and memory utilization charts across all running tasks.
The task detail page displays:
QUEUED - Task is waiting to executeWORKING - Task is currently runningCOMPLETED - Task finished successfullyFAILED - Task encountered an error or non-zero exit codeCANCELED - Task was manually canceledTask logs are captured and displayed in the Chalk dashboard. You can use standard print() statements which will appear in your task logs. You can also use chalk_logger in your script for structured logging:
from chalk import chalk_logger
def process_data(batch_size: str):
batch_size_int = int(batch_size)
chalk_logger.info(f"Starting data processing with batch_size={batch_size_int}")
# Your processing logic
for i in range(batch_size_int):
chalk_logger.debug(f"Processing batch {i+1}/{batch_size_int}")
# ... process data ...
chalk_logger.info("Data processing completed successfully")chalk_logger provides:
You can execute class methods using the double-colon syntax:
# File-based class method
chalk task run scripts/processor.py::DataProcessor::run
# Module-based class method
chalk task run mypackage.processors::ETLProcessor::execute --moduleIf a task remains in QUEUED status:
ModuleNotFoundError: No module named 'mypackage'
Solutions:
requirements.txt or pyproject.tomlIf arguments aren’t being passed correctly:
key=value format for kwargs, plain values for positional args