# Modal SDK Modal is a serverless cloud compute platform that allows developers to run code in the cloud without managing infrastructure. The Modal SDKs provide convenient, on-demand access to serverless cloud compute from Python, JavaScript/TypeScript, and Go applications. Core functionality includes creating and managing Sandboxes (isolated container environments), calling deployed Functions, working with persistent storage (Volumes), managing Secrets, and building custom container Images. The SDKs are designed for a variety of use cases including running AI/ML workloads, executing arbitrary code in isolated environments, building coding agents, and orchestrating distributed computing tasks. The Python SDK (v1.4.2+) is the most feature-complete and allows defining Modal Functions, while the JavaScript (v0.7.4) and Go (v0.7.4) SDKs focus on interacting with deployed resources and creating Sandboxes. All SDKs provide similar APIs for resource management with language-idiomatic patterns. ## Installation Install the Modal SDK for your language of choice. ```bash # Python (requires Python 3.10-3.14) pip install modal # or uv pip install modal # JavaScript/TypeScript (requires Node 22+) npm install modal # Go (requires Go 1.23+) go get -u github.com/modal-labs/modal-client/go ``` ## Authentication Setup Set up Modal authentication via CLI or environment variables. ```bash # Option 1: Interactive setup (requires Python SDK) python3 -m modal setup # Option 2: Environment variables export MODAL_TOKEN_ID=ak-your-token-id export MODAL_TOKEN_SECRET=as-your-token-secret # Optional: Custom config file path export MODAL_CONFIG_PATH=~/.modal.toml ``` ## Creating a Modal Client Initialize the Modal client to interact with Modal resources. ```typescript // JavaScript/TypeScript import { ModalClient } from "modal"; const modal = new ModalClient(); // Access Modal resources through the client const app = await modal.apps.fromName("my-app", { createIfMissing: true }); ``` ```go // Go package main import ( "context" "log" modal "github.com/modal-labs/modal-client/go" ) func main() { ctx := context.Background() mc, err := modal.NewClient() if err != nil { log.Fatalf("Failed to create client: %v", err) } app, err := mc.Apps.FromName(ctx, "my-app", &modal.AppFromNameParams{CreateIfMissing: true}) if err != nil { log.Fatalf("Failed to get or create App: %v", err) } } ``` ## Creating a Sandbox Create an isolated container environment to run arbitrary code. Sandboxes support custom images, GPU access, volumes, secrets, and network configuration. ```typescript // JavaScript/TypeScript import { ModalClient } from "modal"; const modal = new ModalClient(); const app = await modal.apps.fromName("sandbox-example", { createIfMissing: true }); const image = modal.images.fromRegistry("alpine:3.21"); const sb = await modal.sandboxes.create(app, image, { command: ["cat"] }); console.log("Sandbox:", sb.sandboxId); // Write to stdin and read from stdout await sb.stdin.writeText("Hello from Modal!"); await sb.stdin.close(); console.log("Output:", await sb.stdout.readText()); // Clean up await sb.terminate(); ``` ```go // Go package main import ( "context" "fmt" "io" "log" modal "github.com/modal-labs/modal-client/go" ) func main() { ctx := context.Background() mc, err := modal.NewClient() if err != nil { log.Fatalf("Failed to create client: %v", err) } app, err := mc.Apps.FromName(ctx, "sandbox-example", &modal.AppFromNameParams{CreateIfMissing: true}) if err != nil { log.Fatalf("Failed to get or create App: %v", err) } image := mc.Images.FromRegistry("alpine:3.21", nil) sb, err := mc.Sandboxes.Create(ctx, app, image, &modal.SandboxCreateParams{ Command: []string{"cat"}, }) if err != nil { log.Fatalf("Failed to create Sandbox: %v", err) } defer sb.Terminate(context.Background(), nil) // Write to stdin and read from stdout sb.Stdin.Write([]byte("Hello from Modal!")) sb.Stdin.Close() output, _ := io.ReadAll(sb.Stdout) fmt.Printf("Output: %s\n", string(output)) } ``` ## Executing Commands in a Sandbox Execute commands in a running Sandbox and capture stdout/stderr. ```typescript // JavaScript/TypeScript import { ModalClient } from "modal"; const modal = new ModalClient(); const app = await modal.apps.fromName("exec-example", { createIfMissing: true }); const image = modal.images.fromRegistry("python:3.13-slim"); const sb = await modal.sandboxes.create(app, image); console.log("Started Sandbox:", sb.sandboxId); try { const p = await sb.exec( ["python", "-c", "print('Hello from Python!')"], { stdout: "pipe", stderr: "pipe" } ); const [stdout, stderr] = await Promise.all([ p.stdout.readText(), p.stderr.readText(), ]); console.log("stdout:", stdout); console.log("Return code:", await p.wait()); } finally { await sb.terminate(); } ``` ```go // Go package main import ( "context" "fmt" "io" "log" modal "github.com/modal-labs/modal-client/go" ) func main() { ctx := context.Background() mc, _ := modal.NewClient() app, _ := mc.Apps.FromName(ctx, "exec-example", &modal.AppFromNameParams{CreateIfMissing: true}) image := mc.Images.FromRegistry("python:3.13-slim", nil) sb, _ := mc.Sandboxes.Create(ctx, app, image, nil) defer sb.Terminate(context.Background(), nil) p, _ := sb.Exec(ctx, []string{"python", "-c", "print('Hello from Python!')"}, nil) stdout, _ := io.ReadAll(p.Stdout) fmt.Printf("stdout: %s", string(stdout)) returnCode, _ := p.Wait(ctx) fmt.Println("Return code:", returnCode) } ``` ## Calling Deployed Functions Look up and call Functions that have been deployed to Modal using the Python SDK. ```typescript // JavaScript/TypeScript import { ModalClient } from "modal"; const modal = new ModalClient(); // Look up a deployed function by app name and function name const echo = await modal.functions.fromName("my-app", "echo_string"); // Call with positional arguments let result = await echo.remote(["Hello world!"]); console.log(result); // Call with keyword arguments result = await echo.remote([], { s: "Hello world!" }); console.log(result); ``` ```go // Go package main import ( "context" "fmt" "log" modal "github.com/modal-labs/modal-client/go" ) func main() { ctx := context.Background() mc, _ := modal.NewClient() // Look up a deployed function echo, err := mc.Functions.FromName(ctx, "my-app", "echo_string", nil) if err != nil { log.Fatalf("Failed to get Function: %v", err) } // Call with positional arguments ret, _ := echo.Remote(ctx, []any{"Hello world!"}, nil) fmt.Println("Response:", ret) // Call with keyword arguments ret, _ = echo.Remote(ctx, nil, map[string]any{"s": "Hello world!"}) fmt.Println("Response:", ret) } ``` ## Spawning Functions Asynchronously Spawn a Function call and retrieve results later. ```typescript // JavaScript/TypeScript import { ModalClient } from "modal"; const modal = new ModalClient(); const echo = await modal.functions.fromName("my-app", "echo_string"); // Spawn the Function asynchronously const functionCall = await echo.spawn([], { s: "Hello world!" }); // Do other work... // Get the result when ready const result = await functionCall.get(); console.log(result); ``` ```go // Go package main import ( "context" "fmt" modal "github.com/modal-labs/modal-client/go" ) func main() { ctx := context.Background() mc, _ := modal.NewClient() echo, _ := mc.Functions.FromName(ctx, "my-app", "echo_string", nil) // Spawn the Function asynchronously fc, _ := echo.Spawn(ctx, nil, map[string]any{"s": "Hello world!"}) // Get the result when ready ret, _ := fc.Get(ctx, nil) fmt.Println("Response:", ret) } ``` ## Calling Modal Classes (Cls) Instantiate and call methods on Modal Classes deployed via the Python SDK. ```typescript // JavaScript/TypeScript import { ModalClient } from "modal"; const modal = new ModalClient(); // Look up a deployed class const cls = await modal.cls.fromName("my-app", "MyClass"); const instance = await cls.instance(); const method = instance.method("process"); // Call the class method let result = await method.remote(["input data"]); console.log(result); // Call with keyword arguments result = await method.remote([], { data: "input data" }); console.log(result); ``` ```go // Go package main import ( "context" "fmt" modal "github.com/modal-labs/modal-client/go" ) func main() { ctx := context.Background() mc, _ := modal.NewClient() // Look up a deployed class cls, _ := mc.Cls.FromName(ctx, "my-app", "MyClass", nil) instance, _ := cls.Instance(ctx, nil) method, _ := instance.Method("process") // Call the class method result, _ := method.Remote(ctx, []any{"input data"}, nil) fmt.Println("Response:", result) } ``` ## Working with Volumes Mount persistent Volumes to Sandboxes for data sharing and persistence. ```typescript // JavaScript/TypeScript import { ModalClient } from "modal"; const modal = new ModalClient(); const app = await modal.apps.fromName("volume-example", { createIfMissing: true }); const image = modal.images.fromRegistry("alpine:3.21"); // Create or get an existing volume const volume = await modal.volumes.fromName("my-volume", { createIfMissing: true }); // Writer sandbox - mounts volume with read/write access const writer = await modal.sandboxes.create(app, image, { command: ["sh", "-c", "echo 'Hello from writer!' > /mnt/volume/message.txt"], volumes: { "/mnt/volume": volume }, }); await writer.wait(); console.log("Writer finished"); // Reader sandbox - mounts volume as read-only const reader = await modal.sandboxes.create(app, image, { volumes: { "/mnt/volume": volume.readOnly() }, }); const proc = await reader.exec(["cat", "/mnt/volume/message.txt"]); console.log("Reader output:", await proc.stdout.readText()); await writer.terminate(); await reader.terminate(); ``` ```go // Go package main import ( "context" "fmt" "io" modal "github.com/modal-labs/modal-client/go" ) func main() { ctx := context.Background() mc, _ := modal.NewClient() app, _ := mc.Apps.FromName(ctx, "volume-example", &modal.AppFromNameParams{CreateIfMissing: true}) image := mc.Images.FromRegistry("alpine:3.21", nil) // Create or get an existing volume volume, _ := mc.Volumes.FromName(ctx, "my-volume", &modal.VolumeFromNameParams{CreateIfMissing: true}) // Writer sandbox writer, _ := mc.Sandboxes.Create(ctx, app, image, &modal.SandboxCreateParams{ Command: []string{"sh", "-c", "echo 'Hello from writer!' > /mnt/volume/message.txt"}, Volumes: map[string]*modal.Volume{"/mnt/volume": volume}, }) writer.Wait(ctx) defer writer.Terminate(context.Background(), nil) // Reader sandbox with read-only volume reader, _ := mc.Sandboxes.Create(ctx, app, image, &modal.SandboxCreateParams{ Volumes: map[string]*modal.Volume{"/mnt/volume": volume.ReadOnly()}, }) defer reader.Terminate(context.Background(), nil) proc, _ := reader.Exec(ctx, []string{"cat", "/mnt/volume/message.txt"}, nil) output, _ := io.ReadAll(proc.Stdout) fmt.Printf("Reader output: %s", string(output)) } ``` ## Working with Secrets Inject secrets as environment variables into Sandboxes. ```typescript // JavaScript/TypeScript import { ModalClient } from "modal"; const modal = new ModalClient(); const app = await modal.apps.fromName("secrets-example", { createIfMissing: true }); const image = modal.images.fromRegistry("alpine:3.21"); // Get a named secret from Modal const namedSecret = await modal.secrets.fromName("my-api-key", { requiredKeys: ["API_KEY"], }); // Create an ephemeral secret from key-value pairs const ephemeralSecret = await modal.secrets.fromObject({ DATABASE_URL: "postgres://localhost/mydb", }); const sb = await modal.sandboxes.create(app, image, { command: ["sh", "-lc", "printenv | grep -E '^API_KEY|DATABASE_URL='"], secrets: [namedSecret, ephemeralSecret], }); console.log("Environment variables:"); console.log(await sb.stdout.readText()); await sb.terminate(); ``` ```go // Go package main import ( "context" "fmt" "io" modal "github.com/modal-labs/modal-client/go" ) func main() { ctx := context.Background() mc, _ := modal.NewClient() app, _ := mc.Apps.FromName(ctx, "secrets-example", &modal.AppFromNameParams{CreateIfMissing: true}) image := mc.Images.FromRegistry("alpine:3.21", nil) // Get a named secret namedSecret, _ := mc.Secrets.FromName(ctx, "my-api-key", &modal.SecretFromNameParams{ RequiredKeys: []string{"API_KEY"}, }) // Create an ephemeral secret ephemeralSecret, _ := mc.Secrets.FromMap(ctx, map[string]string{ "DATABASE_URL": "postgres://localhost/mydb", }, nil) sb, _ := mc.Sandboxes.Create(ctx, app, image, &modal.SandboxCreateParams{ Command: []string{"sh", "-lc", "printenv | grep -E '^API_KEY|DATABASE_URL='"}, Secrets: []*modal.Secret{namedSecret, ephemeralSecret}, }) defer sb.Terminate(context.Background(), nil) output, _ := io.ReadAll(sb.Stdout) fmt.Printf("Environment variables:\n%s", string(output)) } ``` ## Building Custom Images Build custom container images with Dockerfile commands and secrets. ```typescript // JavaScript/TypeScript import { ModalClient } from "modal"; const modal = new ModalClient(); const app = await modal.apps.fromName("image-example", { createIfMissing: true }); // Build a custom image with Dockerfile commands const image = modal.images .fromRegistry("alpine:3.21") .dockerfileCommands(["RUN apk add --no-cache curl=$CURL_VERSION"], { secrets: [ await modal.secrets.fromObject({ CURL_VERSION: "8.12.1-r1" }), ], }) .dockerfileCommands(["ENV SERVER=ipconfig.me"]); const sb = await modal.sandboxes.create(app, image, { command: ["sh", "-c", "curl -Ls $SERVER"], }); console.log("Output:", await sb.stdout.readText()); await sb.terminate(); ``` ```go // Go package main import ( "context" "fmt" "io" modal "github.com/modal-labs/modal-client/go" ) func main() { ctx := context.Background() mc, _ := modal.NewClient() app, _ := mc.Apps.FromName(ctx, "image-example", &modal.AppFromNameParams{CreateIfMissing: true}) // Create a secret for build-time use secret, _ := mc.Secrets.FromMap(ctx, map[string]string{ "CURL_VERSION": "8.12.1-r1", }, nil) // Build a custom image image := mc.Images.FromRegistry("alpine:3.21", nil). DockerfileCommands([]string{"RUN apk add --no-cache curl=$CURL_VERSION"}, &modal.ImageDockerfileCommandsParams{ Secrets: []*modal.Secret{secret}, }). DockerfileCommands([]string{"ENV SERVER=ipconfig.me"}, nil) sb, _ := mc.Sandboxes.Create(ctx, app, image, &modal.SandboxCreateParams{ Command: []string{"sh", "-c", "curl -Ls $SERVER"}, }) defer sb.Terminate(context.Background(), nil) output, _ := io.ReadAll(sb.Stdout) fmt.Println("Output:", string(output)) } ``` ## Creating Sandboxes with GPU Create Sandboxes with GPU acceleration for ML/AI workloads. ```typescript // JavaScript/TypeScript import { ModalClient } from "modal"; const modal = new ModalClient(); const app = await modal.apps.fromName("gpu-example", { createIfMissing: true }); const image = modal.images.fromRegistry("nvidia/cuda:12.4.0-devel-ubuntu22.04"); // Create a Sandbox with an A10G GPU const sb = await modal.sandboxes.create(app, image, { gpu: "A10G" }); console.log("Started Sandbox with A10G GPU:", sb.sandboxId); try { const gpuCheck = await sb.exec(["nvidia-smi"]); console.log(await gpuCheck.stdout.readText()); } finally { await sb.terminate(); } ``` ```go // Go package main import ( "context" "fmt" "io" modal "github.com/modal-labs/modal-client/go" ) func main() { ctx := context.Background() mc, _ := modal.NewClient() app, _ := mc.Apps.FromName(ctx, "gpu-example", &modal.AppFromNameParams{CreateIfMissing: true}) image := mc.Images.FromRegistry("nvidia/cuda:12.4.0-devel-ubuntu22.04", nil) // Create a Sandbox with GPU sb, _ := mc.Sandboxes.Create(ctx, app, image, &modal.SandboxCreateParams{ GPU: "A10G", // Options: "T4", "A10G", "A100", "A100-80GB", "H100", etc. }) defer sb.Terminate(context.Background(), nil) p, _ := sb.Exec(ctx, []string{"nvidia-smi"}, nil) output, _ := io.ReadAll(p.Stdout) fmt.Printf("%s\n", string(output)) } ``` ## Exposing Ports with Tunnels Expose TCP ports from a Sandbox via secure tunnels. ```typescript // JavaScript/TypeScript import { ModalClient } from "modal"; const modal = new ModalClient(); const app = await modal.apps.fromName("tunnel-example", { createIfMissing: true }); const image = modal.images.fromRegistry("python:3.12-alpine"); // Create a Sandbox with an HTTP server and expose port 8000 const sb = await modal.sandboxes.create(app, image, { command: ["python3", "-m", "http.server", "8000"], encryptedPorts: [8000], timeoutMs: 60000, idleTimeoutMs: 30000, }); // Wait for server to start await new Promise((resolve) => setTimeout(resolve, 3000)); // Get tunnel information const tunnels = await sb.tunnels(); const tunnel = tunnels[8000]; console.log("Tunnel URL:", tunnel.url); // Make a request to the tunneled server const response = await fetch(tunnel.url); console.log("Response:", await response.text()); await sb.terminate(); ``` ```go // Go package main import ( "context" "fmt" "io" "net/http" "time" modal "github.com/modal-labs/modal-client/go" ) func main() { ctx := context.Background() mc, _ := modal.NewClient() app, _ := mc.Apps.FromName(ctx, "tunnel-example", &modal.AppFromNameParams{CreateIfMissing: true}) image := mc.Images.FromRegistry("python:3.12-alpine", nil) sb, _ := mc.Sandboxes.Create(ctx, app, image, &modal.SandboxCreateParams{ Command: []string{"python3", "-m", "http.server", "8000"}, EncryptedPorts: []int{8000}, Timeout: 1 * time.Minute, IdleTimeout: 30 * time.Second, }) defer sb.Terminate(context.Background(), nil) time.Sleep(3 * time.Second) tunnels, _ := sb.Tunnels(ctx, 30*time.Second) tunnel := tunnels[8000] fmt.Println("Tunnel URL:", tunnel.URL()) resp, _ := http.Get(tunnel.URL()) defer resp.Body.Close() body, _ := io.ReadAll(resp.Body) fmt.Printf("Response:\n%s\n", string(body)) } ``` ## Filesystem Operations Read and write files directly in a Sandbox filesystem. ```typescript // JavaScript/TypeScript import { ModalClient } from "modal"; const modal = new ModalClient(); const app = await modal.apps.fromName("fs-example", { createIfMissing: true }); const image = modal.images.fromRegistry("alpine:3.21"); const sb = await modal.sandboxes.create(app, image); try { const encoder = new TextEncoder(); const decoder = new TextDecoder(); // Write a file const writeHandle = await sb.open("/tmp/example.txt", "w"); await writeHandle.write(encoder.encode("Hello, Modal filesystem!\n")); await writeHandle.write(encoder.encode("Line 2\n")); await writeHandle.close(); // Read the file const readHandle = await sb.open("/tmp/example.txt", "r"); const content = await readHandle.read(); console.log("File content:", decoder.decode(content)); await readHandle.close(); // Append to the file const appendHandle = await sb.open("/tmp/example.txt", "a"); await appendHandle.write(encoder.encode("Appended line\n")); await appendHandle.close(); } finally { await sb.terminate(); } ``` ```go // Go package main import ( "context" "fmt" "io" modal "github.com/modal-labs/modal-client/go" ) func main() { ctx := context.Background() mc, _ := modal.NewClient() app, _ := mc.Apps.FromName(ctx, "fs-example", &modal.AppFromNameParams{CreateIfMissing: true}) image := mc.Images.FromRegistry("alpine:3.21", nil) sb, _ := mc.Sandboxes.Create(ctx, app, image, &modal.SandboxCreateParams{}) defer sb.Terminate(context.Background(), nil) // Write a file writeFile, _ := sb.Open(ctx, "/tmp/example.txt", "w") writeFile.Write([]byte("Hello, Modal filesystem!\n")) writeFile.Close() // Read the file reader, _ := sb.Open(ctx, "/tmp/example.txt", "r") content, _ := io.ReadAll(reader) fmt.Printf("File content:\n%s\n", string(content)) reader.Close() } ``` ## Snapshotting Sandbox Filesystem Create an image snapshot from a Sandbox's filesystem state. ```typescript // JavaScript/TypeScript import { ModalClient } from "modal"; const modal = new ModalClient(); const app = await modal.apps.fromName("snapshot-example", { createIfMissing: true }); const baseImage = modal.images.fromRegistry("alpine:3.21"); // Create first sandbox and set up state const sb = await modal.sandboxes.create(app, baseImage); await sb.exec(["mkdir", "-p", "/app/data"]); await sb.exec(["sh", "-c", "echo 'Snapshot data' > /app/data/info.txt"]); // Create a snapshot of the filesystem const snapshotImage = await sb.snapshotFilesystem(); console.log("Snapshot Image ID:", snapshotImage.imageId); await sb.terminate(); // Create a new sandbox from the snapshot const sb2 = await modal.sandboxes.create(app, snapshotImage); const proc = await sb2.exec(["cat", "/app/data/info.txt"]); console.log("Data from snapshot:", await proc.stdout.readText()); await sb2.terminate(); ``` ```go // Go package main import ( "context" "fmt" "io" "time" modal "github.com/modal-labs/modal-client/go" ) func main() { ctx := context.Background() mc, _ := modal.NewClient() app, _ := mc.Apps.FromName(ctx, "snapshot-example", &modal.AppFromNameParams{CreateIfMissing: true}) baseImage := mc.Images.FromRegistry("alpine:3.21", nil) // Create and set up first sandbox sb, _ := mc.Sandboxes.Create(ctx, app, baseImage, &modal.SandboxCreateParams{}) sb.Exec(ctx, []string{"mkdir", "-p", "/app/data"}, nil) sb.Exec(ctx, []string{"sh", "-c", "echo 'Snapshot data' > /app/data/info.txt"}, nil) // Create filesystem snapshot snapshotImage, _ := sb.SnapshotFilesystem(ctx, 55*time.Second) fmt.Printf("Snapshot Image ID: %s\n", snapshotImage.ImageID) sb.Terminate(ctx, nil) // Create new sandbox from snapshot sb2, _ := mc.Sandboxes.Create(ctx, app, snapshotImage, nil) defer sb2.Terminate(context.Background(), nil) proc, _ := sb2.Exec(ctx, []string{"cat", "/app/data/info.txt"}, nil) content, _ := io.ReadAll(proc.Stdout) fmt.Printf("Data from snapshot: %s", string(content)) } ``` ## Polling Sandbox Status Check if a Sandbox is still running and get its exit code. ```typescript // JavaScript/TypeScript import { ModalClient } from "modal"; const modal = new ModalClient(); const app = await modal.apps.fromName("poll-example", { createIfMissing: true }); const image = modal.images.fromRegistry("alpine:3.21"); // Create a sandbox that waits for input then exits with code 42 const sb = await modal.sandboxes.create(app, image, { command: ["sh", "-c", "read line; exit 42"], }); // Poll returns undefined while running console.log("Poll while running:", await sb.poll()); // Send input to trigger completion await sb.stdin.writeText("done"); await sb.stdin.close(); // Wait for completion and get exit code const exitCode = await sb.wait(); console.log("Exit code:", exitCode); // Poll returns exit code after completion console.log("Poll after completion:", await sb.poll()); ``` ```go // Go package main import ( "context" "fmt" modal "github.com/modal-labs/modal-client/go" ) func main() { ctx := context.Background() mc, _ := modal.NewClient() app, _ := mc.Apps.FromName(ctx, "poll-example", &modal.AppFromNameParams{CreateIfMissing: true}) image := mc.Images.FromRegistry("alpine:3.21", nil) sb, _ := mc.Sandboxes.Create(ctx, app, image, &modal.SandboxCreateParams{ Command: []string{"sh", "-c", "read line; exit 42"}, }) defer sb.Terminate(context.Background(), nil) // Poll returns nil while running initialPoll, _ := sb.Poll(ctx) fmt.Printf("Poll while running: %v\n", initialPoll) // Send input to trigger completion sb.Stdin.Write([]byte("done\n")) sb.Stdin.Close() exitCode, _ := sb.Wait(ctx) fmt.Printf("Exit code: %d\n", exitCode) // Poll returns exit code after completion finalPoll, _ := sb.Poll(ctx) fmt.Printf("Poll after completion: %d\n", *finalPoll) } ``` ## Python SDK - Defining Functions Define serverless functions using the Python SDK (functions can then be called from any SDK). ```python # Python import modal app = modal.App("my-app") @app.function() def echo_string(s: str) -> str: """Echo the input string back.""" return f"Echo: {s}" @app.function(gpu="A10G") def run_inference(prompt: str) -> str: """Run ML inference with GPU acceleration.""" # Your ML code here return f"Result for: {prompt}" # Deploy with: modal deploy my_app.py ``` ## Python SDK - Defining Classes Define stateful classes with the Python SDK for persistent instances. ```python # Python import modal app = modal.App("my-app") @app.cls(gpu="T4") class MyModel: @modal.enter() def load_model(self): # Load model once when container starts self.model = load_my_model() @modal.method() def predict(self, input_data: str) -> str: return self.model.predict(input_data) # Deploy with: modal deploy my_app.py # Then call from JS/Go using modal.cls.fromName() ``` ## Python SDK - Creating Sandboxes Create and interact with Sandboxes directly in Python. ```python # Python import modal app = modal.App.lookup("sandbox-example", create_if_missing=True) # Create a sandbox sandbox = modal.Sandbox.create( "python", "-c", "print('Hello from sandbox!')", image=modal.Image.debian_slim().pip_install("numpy"), timeout=300, app=app, ) # Read output print(sandbox.stdout.read()) # Execute additional commands proc = sandbox.exec("python", "-c", "import numpy; print(numpy.__version__)") print(proc.stdout.read()) # Clean up sandbox.terminate() ``` ## Python SDK - Readiness Probes Configure readiness probes to wait for Sandboxes to be ready. ```python # Python import modal app = modal.App.lookup("probe-example", create_if_missing=True) # Wait until a TCP port is accepting connections tcp_probe = modal.Probe.with_tcp(8080) # Or wait until a command succeeds exec_probe = modal.Probe.with_exec("sh", "-c", "test -f /tmp/ready") sandbox = modal.Sandbox.create( "python", "-m", "http.server", "8080", readiness_probe=tcp_probe, app=app, ) # Block until the probe succeeds sandbox.wait_until_ready() print("Server is ready!") sandbox.terminate() ``` ## Summary The Modal SDKs enable developers to leverage serverless cloud computing across Python, JavaScript/TypeScript, and Go applications. The primary use cases include: running AI/ML inference with GPU acceleration, executing untrusted code in isolated Sandboxes, building AI coding agents, orchestrating distributed compute jobs, and creating custom container-based workflows. The SDKs provide a unified interface for managing cloud resources including Functions, Classes, Sandboxes, Volumes, Secrets, and Images. Integration patterns typically involve deploying Functions and Classes using the Python SDK, then calling them from any language using the JS/Go SDKs. Sandboxes are commonly used for agent-based systems where arbitrary code execution is required. All SDKs support volume mounting for persistent storage, secret injection for credentials, custom image building, and network tunneling for exposing services. The APIs follow language-idiomatic conventions while maintaining consistent functionality across all three SDKs, making it easy to integrate Modal into polyglot architectures.