A sandbox is an isolated container that you start from Python, run commands in, and terminate when you are done. In this tutorial you will:

  • Start a sandbox and run a command in it
  • Run code that needs a package
  • Save files to a volume, so that they outlive the sandbox that wrote them
  • Read those files from a second sandbox
  • Delete everything you created

​
Before you start

You need:

  • A Chalk account and an environment to work in.
  • A role that can create sandboxes and run commands in them: the deploy.create and deploy.redeploy permissions. If you created your Chalk team yourself, you already have them. Otherwise, ask an admin for a role that includes them. See Permissions.
  • Sandboxes turned on in that environment. They are on by default in environments that Chalk hosts, including Chalk Serverless. In a self-hosted environment, see One-time setup for admins.

You do not need a Chalk project or chalk init, and you do not deploy anything with chalk apply. Every sandbox and volume in this tutorial is created by the tutorial and deleted in the last step.

Set up the Python environment that will run the tutorial:

  • If you followed the Setup Guide, chalk init already installed chalkcompute in your project. Start Python from your project folder with uv run python, or open a Jupyter notebook that uses the project’s .venv.
  • Otherwise, install the Chalk CLI, run chalk login, and install chalkcompute with pip install chalkcompute. Start Python, or a Jupyter notebook, from the folder where you ran chalk login, so that chalkcompute finds your login. See Logins and environments.

Run each step’s code in one Python session, in order. Later steps use the sandboxes and the volume that earlier steps create.


​
Step 1: Start a sandbox and run a command

import chalkcompute

sandbox = chalkcompute.Sandbox(
    image=chalkcompute.Image.debian_slim("3.12"),
    name="tutorial-first",
).run()

result = sandbox.exec("python3", "--version")
print(result.stdout_text)
Python 3.12.15

run() builds the image, starts the sandbox, and waits until it is ready. The image here is a slim Debian image with Python 3.12. Chalk caches each image it builds, so starting another sandbox from the same image skips the build.

exec runs a process inside the sandbox and returns when the process exits. stdout_text and stderr_text hold everything the process printed.


​
Step 2: Run code that needs a package

An image can include Python packages. Start a second sandbox from an image that installs NumPy, and run a line of Python in it:

numpy_sandbox = chalkcompute.Sandbox(
    image=chalkcompute.Image.debian_slim("3.12").pip_install(["numpy"]),
    name="tutorial-numpy",
).run()

result = numpy_sandbox.exec(
    "python3", "-c", "import numpy; print(numpy.arange(10).sum())"
)
print(result.stdout_text)
45

The first time Chalk builds an image, run() waits for the build, which can take a few minutes.

The first sandbox is still running. Terminate both, since the next steps start new ones:

sandbox.terminate()
numpy_sandbox.terminate()

When a sandbox terminates, its filesystem is deleted with it. To keep a file after the sandbox is gone, save it to a volume.


​
Step 3: Save a file to a volume

Create a volume named tutorial-notes by uploading a file to it from your machine:

volume = chalkcompute.Volume("tutorial-notes")
volume.put_file("from-my-machine.txt", b"Uploaded from my machine\n")

Volume("tutorial-notes") does not contact Chalk by itself. The volume is created the first time you read or write through it, here with put_file.

Now start a sandbox with the volume mounted at /data, and write a second file from inside it. Inside the sandbox, the volume is an ordinary directory:

writer = chalkcompute.Sandbox(
    image=chalkcompute.Image.debian_slim("3.12"),
    name="tutorial-writer",
    volumes=[("tutorial-notes", "/data")],
).run()

writer.exec("sh", "-c", "echo 'Saved by tutorial-writer' > /data/note.txt")
result = writer.exec("/data/.chalk-volume/commit")
print(result.stdout_text)
writer.terminate()
published Chalk Volume version 2

Writes to a mounted volume stay inside the sandbox until they are committed. /data/.chalk-volume/commit commits them and waits until the volume has saved them as a new version. A sandbox also commits its writes when it terminates, but that final commit has a time limit, so commit before you terminate a sandbox whose writes you need. For the other ways to commit, see Syncing a mounted volume.


​
Step 4: Read the files from a second sandbox

The writer is gone, and its file is still on the volume. Start a new sandbox with the same volume mounted, and read both files:

reader = chalkcompute.Sandbox(
    image=chalkcompute.Image.debian_slim("3.12"),
    name="tutorial-reader",
    volumes=[("tutorial-notes", "/data")],
).run()

result = reader.exec("sh", "-c", "cat /data/from-my-machine.txt /data/note.txt")
print(result.stdout_text)
Uploaded from my machine
Saved by tutorial-writer

Any number of sandboxes can mount the same volume. Each one sees the volume’s latest committed version when it starts.


​
Step 5: Clean up

Terminate the reader and delete the volume:

reader.terminate()
volume.delete()

delete() removes the volume and every version of it. The sandboxes from the earlier steps were terminated when you finished with them, so nothing from this tutorial is left running.


​
Next steps