Installation
go get github.com/daytonaio/daytona/libs/sdk-go
Quick Start
package main
import (
"context"
"log"
"time"
"github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona"
"github.com/daytonaio/daytona/libs/sdk-go/pkg/options"
"github.com/daytonaio/daytona/libs/sdk-go/pkg/types"
)
func main() {
// Create client using environment variables
client, err := daytona.NewClient()
if err != nil {
log.Fatal(err)
}
ctx := context.Background()
// Create a sandbox
params := types.SnapshotParams{
SandboxBaseParams: types.SandboxBaseParams{
Language: types.CodeLanguagePython,
},
}
sandbox, err := client.Create(ctx, params, options.WithTimeout(90*time.Second))
if err != nil {
log.Fatal(err)
}
log.Printf("Created sandbox: %s (ID: %s)\n", sandbox.Name, sandbox.ID)
// Execute a command
result, err := sandbox.Process.ExecuteCommand(ctx, "echo 'Hello, World!'")
if err != nil {
log.Fatal(err)
}
log.Printf("Output: %s\n", result.Result)
// Clean up
if err := sandbox.Delete(ctx); err != nil {
log.Printf("Failed to delete: %v", err)
}
}
Configuration
Using Environment Variables
Set the following environment variables:export DAYTONA_API_KEY="your-api-key"
export DAYTONA_API_URL="https://app.daytona.io/api" # Optional
export DAYTONA_TARGET="us" # Optional
import "github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona"
client, err := daytona.NewClient()
if err != nil {
log.Fatal(err)
}
Using Configuration Object
import (
"github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona"
"github.com/daytonaio/daytona/libs/sdk-go/pkg/types"
)
config := &types.DaytonaConfig{
APIKey: "your-api-key",
}
client, err := daytona.NewClientWithConfig(config)
if err != nil {
log.Fatal(err)
}
Sandbox Management
Creating Sandboxes
Basic Sandbox Creation
import (
"context"
"time"
"github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona"
"github.com/daytonaio/daytona/libs/sdk-go/pkg/options"
"github.com/daytonaio/daytona/libs/sdk-go/pkg/types"
)
ctx := context.Background()
params := types.SnapshotParams{
SandboxBaseParams: types.SandboxBaseParams{
Language: types.CodeLanguagePython,
},
}
sandbox, err := client.Create(ctx, params, options.WithTimeout(90*time.Second))
if err != nil {
log.Fatal(err)
}
log.Printf("Created sandbox: %s (ID: %s)\n", sandbox.Name, sandbox.ID)
log.Printf("State: %s\n", sandbox.State)
Customized Sandbox Creation
params := types.SnapshotParams{
SandboxBaseParams: types.SandboxBaseParams{
Language: types.CodeLanguagePython,
EnvVars: map[string]string{
"PYTHON_ENV": "production",
"DEBUG": "false",
},
Labels: map[string]string{
"project": "my-app",
"environment": "production",
},
AutoStopInterval: 60, // Auto-stop after 1 hour
AutoArchiveInterval: 60, // Auto-archive after 1 hour
AutoDeleteInterval: 120, // Auto-delete after 2 hours
},
}
sandbox, err := client.Create(ctx, params, options.WithTimeout(90*time.Second))
if err != nil {
log.Fatal(err)
}
Creating from Custom Image
params := types.ImageParams{
SandboxBaseParams: types.SandboxBaseParams{
Language: types.CodeLanguagePython,
},
Image: &types.Image{
Name: "my-custom-image",
User: "daytona",
},
}
sandbox, err := client.Create(ctx, params, options.WithTimeout(90*time.Second))
if err != nil {
log.Fatal(err)
}
Streaming Build Logs
import "fmt"
params := types.SnapshotParams{
SandboxBaseParams: types.SandboxBaseParams{
Language: types.CodeLanguagePython,
},
}
// Create sandbox and get build logs channel
sandbox, buildLogs, err := client.Create(
ctx,
params,
options.WithTimeout(90*time.Second),
)
if err != nil {
log.Fatal(err)
}
// Read build logs in real-time
go func() {
for logLine := range buildLogs {
fmt.Printf("[BUILD] %s\n", logLine)
}
}()
log.Printf("Sandbox created: %s\n", sandbox.ID)
Listing Sandboxes
// List all sandboxes
page := 1
limit := 10
result, err := client.List(ctx, nil, &page, &limit)
if err != nil {
log.Fatal(err)
}
log.Printf("Total sandboxes: %d\n", result.Total)
for _, sb := range result.Items {
log.Printf("ID: %s, State: %s\n", sb.ID, sb.State)
}
// List with label filter
labels := map[string]string{"project": "my-app"}
result, err = client.List(ctx, labels, &page, &limit)
if err != nil {
log.Fatal(err)
}
Getting a Sandbox
// Get by ID or name
sandbox, err := client.Get(ctx, "sandbox-id-or-name")
if err != nil {
log.Fatal(err)
}
log.Printf("Sandbox: %s (State: %s)\n", sandbox.Name, sandbox.State)
Sandbox Lifecycle
// Stop a sandbox
if err := sandbox.Stop(ctx); err != nil {
log.Fatal(err)
}
log.Printf("Sandbox state: %s\n", sandbox.State)
// Stop with custom timeout
if err := sandbox.StopWithTimeout(ctx, 120*time.Second); err != nil {
log.Fatal(err)
}
// Start a sandbox
if err := sandbox.Start(ctx); err != nil {
log.Fatal(err)
}
log.Printf("Sandbox state: %s\n", sandbox.State)
// Delete a sandbox
if err := sandbox.Delete(ctx); err != nil {
log.Fatal(err)
}
Setting Labels
labels := map[string]string{
"environment": "production",
"project": "my-app",
"team": "backend",
}
if err := sandbox.SetLabels(ctx, labels); err != nil {
log.Fatal(err)
}
log.Printf("Labels set: %v\n", sandbox.Labels)
Code Execution
Executing Commands
// Simple command execution
result, err := sandbox.Process.ExecuteCommand(ctx, "echo 'Hello, World!'")
if err != nil {
log.Fatal(err)
}
if result.ExitCode != 0 {
log.Printf("Command failed: %s\n", result.Result)
} else {
log.Printf("Output: %s\n", result.Result)
}
// Execute with working directory
result, err = sandbox.Process.ExecuteCommand(
ctx,
"ls -la",
options.WithCwd("/home/daytona"),
)
if err != nil {
log.Fatal(err)
}
log.Printf("Files: %s\n", result.Result)
// Execute with environment variables
env := map[string]string{
"MY_VAR": "hello",
}
result, err = sandbox.Process.ExecuteCommand(
ctx,
"echo $MY_VAR",
options.WithEnv(env),
)
if err != nil {
log.Fatal(err)
}
log.Printf("Output: %s\n", result.Result)
Code Interpreter
The Code Interpreter provides stateful Python code execution with real-time streaming:import (
"github.com/daytonaio/daytona/libs/sdk-go/pkg/options"
)
// Get the code interpreter
interpreter := sandbox.CodeInterpreter
// Execute code with real-time streaming
channels, err := interpreter.RunCode(
ctx,
`import time
for i in range(5):
print(f"Step {i+1}")
time.sleep(0.5)
print("Done!")`,
)
if err != nil {
log.Fatal(err)
}
// Read from channels in real-time
go func() {
for msg := range channels.Stdout {
log.Printf("[STDOUT] %s", msg.Text)
}
}()
go func() {
for msg := range channels.Stderr {
log.Printf("[STDERR] %s", msg.Text)
}
}()
go func() {
for execErr := range channels.Errors {
log.Printf("[ERROR] %s: %s\n", execErr.Name, execErr.Value)
}
}()
// Wait for completion
result := <-channels.Done
log.Printf("Execution completed: %s\n", result.Stdout)
Code Execution with Timeout
import "time"
channels, err := interpreter.RunCode(
ctx,
`import time
print("Starting...")
time.sleep(10)
print("This won't print")`,
options.WithInterpreterTimeout(2*time.Second),
)
if err != nil {
log.Fatal(err)
}
result := <-channels.Done
if result.Error != nil {
log.Printf("Timeout error: %s\n", result.Error.Name)
}
File Operations
Uploading Files
// Upload a single file from bytes
content := []byte("Hello, World!")
if err := sandbox.FileSystem.UploadFile(ctx, content, "/tmp/hello.txt"); err != nil {
log.Fatal(err)
}
log.Println("File uploaded")
// Upload from local file
import "os"
data, err := os.ReadFile("local-file.txt")
if err != nil {
log.Fatal(err)
}
if err := sandbox.FileSystem.UploadFile(ctx, data, "/tmp/remote-file.txt"); err != nil {
log.Fatal(err)
}
Downloading Files
// Download a file
content, err := sandbox.FileSystem.DownloadFile(ctx, "/tmp/hello.txt", nil)
if err != nil {
log.Fatal(err)
}
log.Printf("Content: %s\n", string(content))
// Download and save to local file
import "os"
content, err := sandbox.FileSystem.DownloadFile(ctx, "/tmp/data.txt", nil)
if err != nil {
log.Fatal(err)
}
if err := os.WriteFile("local-data.txt", content, 0644); err != nil {
log.Fatal(err)
}
File System Operations
// List files in a directory
files, err := sandbox.FileSystem.ListFiles(ctx, "/tmp")
if err != nil {
log.Fatal(err)
}
for _, file := range files {
log.Printf("%s: %d bytes\n", file.Name, file.Size)
}
// Create a folder
if err := sandbox.FileSystem.CreateFolder(ctx, "/tmp/new-folder"); err != nil {
log.Fatal(err)
}
log.Println("Folder created")
// Search for files
import "github.com/daytonaio/daytona/libs/sdk-go/pkg/options"
matches, err := sandbox.FileSystem.FindFiles(
ctx,
"/tmp",
options.WithPattern("*.txt"),
)
if err != nil {
log.Fatal(err)
}
log.Printf("Found %d files\n", len(matches))
for _, match := range matches {
log.Printf("File: %s\n", match)
}
Git Operations
Cloning Repositories
import "github.com/daytonaio/daytona/libs/sdk-go/pkg/options"
// Clone a public repository
if err := sandbox.Git.Clone(
ctx,
"https://github.com/daytonaio/daytona.git",
"/tmp/daytona",
); err != nil {
log.Fatal(err)
}
log.Println("Repository cloned")
// Clone with authentication
if err := sandbox.Git.Clone(
ctx,
"https://github.com/private/repo.git",
"/tmp/repo",
options.WithUsername("user"),
options.WithPassword("token"),
); err != nil {
log.Fatal(err)
}
// Clone a specific branch
if err := sandbox.Git.Clone(
ctx,
"https://github.com/example/repo.git",
"/tmp/repo",
options.WithBranch("develop"),
); err != nil {
log.Fatal(err)
}
Git Status and Branches
// Get repository status
status, err := sandbox.Git.Status(ctx, "/tmp/repo")
if err != nil {
log.Fatal(err)
}
log.Printf("Current branch: %s\n", status.CurrentBranch)
log.Printf("Files changed: %d\n", len(status.FileStatus))
// List branches
branches, err := sandbox.Git.Branches(ctx, "/tmp/repo")
if err != nil {
log.Fatal(err)
}
for _, branch := range branches {
log.Printf("Branch: %s\n", branch)
}
Committing Changes
// Add files to staging
if err := sandbox.Git.Add(
ctx,
"/tmp/repo",
[]string{"file1.txt", "file2.txt"},
); err != nil {
log.Fatal(err)
}
// Commit changes
if err := sandbox.Git.Commit(
ctx,
"/tmp/repo",
"Add new features",
"Your Name",
"[email protected]",
); err != nil {
log.Fatal(err)
}
// Push changes
if err := sandbox.Git.Push(
ctx,
"/tmp/repo",
options.WithUsername("user"),
options.WithPassword("token"),
); err != nil {
log.Fatal(err)
}
Snapshots and Volumes
Managing Snapshots
// Create a snapshot
import (
"github.com/daytonaio/daytona/libs/sdk-go/pkg/types"
)
params := &types.CreateSnapshotParams{
Name: "my-snapshot",
Image: &types.Image{
Name: "python:3.11",
User: "root",
},
}
snapshot, buildLogs, err := client.Snapshot.Create(ctx, params, 180*time.Second)
if err != nil {
log.Fatal(err)
}
// Stream build logs
go func() {
for logLine := range buildLogs {
log.Printf("[BUILD] %s\n", logLine)
}
}()
log.Printf("Snapshot created: %s\n", snapshot.Name)
// List snapshots
page := 1
limit := 10
snapshots, err := client.Snapshot.List(ctx, &page, &limit)
if err != nil {
log.Fatal(err)
}
for _, snap := range snapshots.Items {
log.Printf("Snapshot: %s\n", snap.Name)
}
// Delete a snapshot
if err := client.Snapshot.Delete(ctx, snapshot); err != nil {
log.Fatal(err)
}
Managing Volumes
// Create a volume
volume, err := client.Volume.Create(ctx, "my-volume")
if err != nil {
log.Fatal(err)
}
log.Printf("Volume created: %s\n", volume.Name)
// List volumes
volumes, err := client.Volume.List(ctx)
if err != nil {
log.Fatal(err)
}
for _, vol := range volumes {
log.Printf("Volume: %s\n", vol.Name)
}
// Delete a volume
if err := client.Volume.Delete(ctx, volume); err != nil {
log.Fatal(err)
}
Error Handling
import (
"errors"
"log"
)
func handleSandbox() error {
client, err := daytona.NewClient()
if err != nil {
return fmt.Errorf("failed to create client: %w", err)
}
ctx := context.Background()
params := types.SnapshotParams{
SandboxBaseParams: types.SandboxBaseParams{
Language: types.CodeLanguagePython,
},
}
sandbox, err := client.Create(ctx, params)
if err != nil {
return fmt.Errorf("failed to create sandbox: %w", err)
}
defer func() {
if err := sandbox.Delete(ctx); err != nil {
log.Printf("Failed to delete sandbox: %v", err)
}
}()
result, err := sandbox.Process.ExecuteCommand(ctx, "invalid-command")
if err != nil {
return fmt.Errorf("command execution failed: %w", err)
}
if result.ExitCode != 0 {
return fmt.Errorf("command failed with exit code %d: %s", result.ExitCode, result.Result)
}
return nil
}
Complete Example
package main
import (
"context"
"fmt"
"log"
"time"
"github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona"
"github.com/daytonaio/daytona/libs/sdk-go/pkg/options"
"github.com/daytonaio/daytona/libs/sdk-go/pkg/types"
)
func main() {
// Initialize client
client, err := daytona.NewClient()
if err != nil {
log.Fatalf("Failed to create client: %v", err)
}
ctx := context.Background()
// Create sandbox with custom configuration
params := types.SnapshotParams{
SandboxBaseParams: types.SandboxBaseParams{
Language: types.CodeLanguagePython,
EnvVars: map[string]string{
"ENV": "production",
},
Labels: map[string]string{
"project": "data-analysis",
},
},
}
sandbox, err := client.Create(ctx, params, options.WithTimeout(90*time.Second))
if err != nil {
log.Fatalf("Failed to create sandbox: %v", err)
}
log.Printf("Created sandbox: %s (ID: %s)\n", sandbox.Name, sandbox.ID)
defer func() {
log.Println("Cleaning up...")
if err := sandbox.Delete(ctx); err != nil {
log.Printf("Failed to delete sandbox: %v", err)
} else {
log.Println("Sandbox deleted")
}
}()
// Upload a Python script
script := []byte(`
import json
data = {'name': 'Alice', 'age': 25}
print(json.dumps(data))
`)
if err := sandbox.FileSystem.UploadFile(ctx, script, "/tmp/analyze.py"); err != nil {
log.Fatalf("Failed to upload file: %v", err)
}
// Install dependencies
installResult, err := sandbox.Process.ExecuteCommand(
ctx,
"pip install pandas",
)
if err != nil {
log.Fatalf("Failed to install pandas: %v", err)
}
if installResult.ExitCode != 0 {
log.Printf("Install failed: %s\n", installResult.Result)
return
}
// Run the script
result, err := sandbox.Process.ExecuteCommand(
ctx,
"python /tmp/analyze.py",
)
if err != nil {
log.Fatalf("Failed to run script: %v", err)
}
if result.ExitCode != 0 {
log.Printf("Script failed: %s\n", result.Result)
return
}
log.Printf("Analysis result: %s\n", result.Result)
}
Best Practices
Always Use Context
import "context"
ctx := context.Background()
// For operations with timeout
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
defer cancel()
sandbox, err := client.Create(ctx, params)
Always Use Defer for Cleanup
sandbox, err := client.Create(ctx, params)
if err != nil {
log.Fatal(err)
}
defer func() {
if err := sandbox.Delete(ctx); err != nil {
log.Printf("Failed to delete sandbox: %v", err)
}
}()
// Use the sandbox...
Check Exit Codes
result, err := sandbox.Process.ExecuteCommand(ctx, "some-command")
if err != nil {
log.Printf("Command failed: %v", err)
return
}
if result.ExitCode != 0 {
log.Printf("Command exited with code %d: %s", result.ExitCode, result.Result)
return
}
log.Printf("Success: %s\n", result.Result)
Use Goroutines for Concurrent Operations
import "sync"
var wg sync.WaitGroup
for i := 0; i < 5; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
sandbox, err := client.Create(ctx, params)
if err != nil {
log.Printf("Failed to create sandbox %d: %v", id, err)
return
}
defer sandbox.Delete(ctx)
// Use sandbox...
}(i)
}
wg.Wait()
Next Steps
SDK Overview
Compare all available SDKs
API Reference
Complete API documentation
Examples
Browse Go examples on GitHub
Python SDK
Learn about the Python SDK