Sandboxes let you run arbitrary code in isolated, containerized environments. Here’s a simple example that creates a sandbox running the cat command:
Python
TypeScript
Go
sandbox_example.py
import modal# Initialize the Modal clientclient = modal.Client()# Get or create an appapp = client.apps.from_name("my-first-app", create_if_missing=True)# Use a base imageimage = client.images.from_registry("alpine:3.21")# Create a sandboxsb = client.sandboxes.create(app, image, command=["cat"])print(f"Sandbox created: {sb.sandbox_id}")# Write to stdin and read from stdoutsb.stdin.write_text("Hello from Modal!")sb.stdin.close()output = sb.stdout.read_text()print(f"Output: {output}")# Clean upsb.terminate()
Run the script:
python sandbox_example.py
sandbox_example.ts
import { ModalClient } from "modal";// Initialize the Modal clientconst modal = new ModalClient();// Get or create an appconst app = await modal.apps.fromName("my-first-app", { createIfMissing: true,});// Use a base imageconst image = modal.images.fromRegistry("alpine:3.21");// Create a sandboxconst sb = await modal.sandboxes.create(app, image, { command: ["cat"] });console.log(`Sandbox created: ${sb.sandboxId}`);// Write to stdin and read from stdoutawait sb.stdin.writeText("Hello from Modal!");await sb.stdin.close();const output = await sb.stdout.readText();console.log(`Output: ${output}`);// Clean upawait sb.terminate();
Run the script:
npx tsx sandbox_example.ts
sandbox_example.go
package mainimport ( "context" "fmt" "io" "log" modal "github.com/modal-labs/modal-client/go")func main() { ctx := context.Background() // Initialize the Modal client mc, err := modal.NewClient() if err != nil { log.Fatalf("Failed to create client: %v", err) } // Get or create an app app, err := mc.Apps.FromName(ctx, "my-first-app", &modal.AppFromNameParams{ CreateIfMissing: true, }) if err != nil { log.Fatalf("Failed to get app: %v", err) } // Use a base image image := mc.Images.FromRegistry("alpine:3.21", nil) // Create a sandbox sb, err := mc.Sandboxes.Create(ctx, app, image, &modal.SandboxCreateParams{ Command: []string{"cat"}, }) if err != nil { log.Fatalf("Failed to create sandbox: %v", err) } fmt.Printf("Sandbox created: %s\n", sb.SandboxID) // Ensure cleanup defer sb.Terminate(context.Background(), nil) // Write to stdin and read from stdout _, err = sb.Stdin.Write([]byte("Hello from Modal!")) if err != nil { log.Fatalf("Failed to write to stdin: %v", err) } sb.Stdin.Close() output, err := io.ReadAll(sb.Stdout) if err != nil { log.Fatalf("Failed to read from stdout: %v", err) } fmt.Printf("Output: %s\n", string(output))}
You can call Modal Functions that have been deployed using the Python SDK. Here’s how to call a function from each SDK:
Python
TypeScript
Go
call_function.py
import modal# Initialize the Modal clientclient = modal.Client()# Get a reference to a deployed functionecho = client.functions.from_name( "my-app", # App name "echo_string" # Function name)# Call the function with positional argumentsresult = echo.remote("Hello world!")print(result)# Call the function with keyword argumentsresult = echo.remote(s="Hello world!")print(result)
The Python SDK also lets you define functions using the @app.function() decorator. See the Modal documentation for details.
call_function.ts
import { ModalClient } from "modal";// Initialize the Modal clientconst modal = new ModalClient();// Get a reference to a deployed functionconst echo = await modal.functions.fromName( "my-app", // App name "echo_string" // Function name);// Call the function with positional argumentslet result = await echo.remote(["Hello world!"]);console.log(result);// Call the function with keyword argumentsresult = await echo.remote([], { s: "Hello world!" });console.log(result);
The TypeScript SDK can only call existing functions. To define new functions, use the Python SDK.
call_function.go
package mainimport ( "context" "fmt" "log" modal "github.com/modal-labs/modal-client/go")func main() { ctx := context.Background() // Initialize the Modal client mc, err := modal.NewClient() if err != nil { log.Fatalf("Failed to create client: %v", err) } // Get a reference to a deployed function echo, err := mc.Functions.FromName( ctx, "my-app", // App name "echo_string", // Function name nil, ) if err != nil { log.Fatalf("Failed to get function: %v", err) } // Call the function with positional arguments result, err := echo.Remote(ctx, []any{"Hello world!"}, nil) if err != nil { log.Fatalf("Failed to call function: %v", err) } fmt.Println("Response:", result) // Call the function with keyword arguments result, err = echo.Remote(ctx, nil, map[string]any{"s": "Hello world!"}) if err != nil { log.Fatalf("Failed to call function: %v", err) } fmt.Println("Response:", result)}
The Go SDK can only call existing functions. To define new functions, use the Python SDK.
Apps are containers for your Modal resources. Every sandbox, function, and resource belongs to an app. You can create apps with from_name() or reference existing ones.
Images define the runtime environment for your code. You can use pre-built images from Docker registries or build custom images with specific dependencies.
Sandboxes are isolated execution environments where you can run arbitrary commands, execute scripts, and interact with the filesystem. They’re perfect for:
Functions are Python callables deployed on Modal that you can invoke from any SDK. They automatically handle serialization, execution, and result retrieval.