Skip to main content
The OpenSandbox C# SDK provides secure, isolated execution environments with comprehensive file system access, command execution, and resource management capabilities.

Installation

dotnet add package Alibaba.OpenSandbox

Core Classes

Sandbox

Main class for creating and managing sandbox instances.

Static Methods

CreateAsync()
Create a new sandbox instance with the specified configuration.
using OpenSandbox;
using OpenSandbox.Config;
using OpenSandbox.Core;

var config = new ConnectionConfig(new ConnectionConfigOptions
{
    Domain = "api.opensandbox.io",
    ApiKey = "your-api-key",
});

await using var sandbox = await Sandbox.CreateAsync(new SandboxCreateOptions
{
    ConnectionConfig = config,
    Image = "python:3.11",
    TimeoutSeconds = 30 * 60,
    Env = new Dictionary<string, string> { ["PYTHONPATH"] = "/workspace" },
    Resource = new Dictionary<string, string> { ["cpu"] = "2", ["memory"] = "4Gi" },
});
options
SandboxCreateOptions
required
Configuration options for sandbox creation.
return
Task<Sandbox>
Fully configured and ready Sandbox instance.
ConnectAsync()
Connect to an existing sandbox instance by ID.
var connected = await Sandbox.ConnectAsync(new SandboxConnectOptions
{
    SandboxId = "existing-sandbox-id",
    ConnectionConfig = config
});
options
SandboxConnectOptions
required
return
Task<Sandbox>
Connected Sandbox instance.

Instance Methods

GetInfoAsync()
Get the current status of the sandbox.
var info = await sandbox.GetInfoAsync();
Console.WriteLine($"State: {info.Status.State}");
Console.WriteLine($"Created: {info.CreatedAt}");
Console.WriteLine($"Expires: {info.ExpiresAt}");
return
Task<SandboxInfo>
Current sandbox status including state and metadata.
GetEndpointAsync()
Get a specific network endpoint for the sandbox.
var endpoint = await sandbox.GetEndpointAsync(80);
Console.WriteLine(endpoint.EndpointAddress);
port
int
required
The port number to get the endpoint for.
return
Task<SandboxEndpoint>
Endpoint information (without scheme, e.g., “localhost:44772”).
GetEndpointUrlAsync()
Get a ready-to-use absolute URL for a port.
var url = await sandbox.GetEndpointUrlAsync(80);
Console.WriteLine(url); // e.g., "http://localhost:44772"
port
int
required
The port number to get the URL for.
return
Task<string>
Absolute URL with scheme.
RenewAsync()
Renew the sandbox expiration time.
await sandbox.RenewAsync(30 * 60); // 30 minutes
timeoutSeconds
int
required
Duration in seconds to extend the expiration.
return
Task
Task that completes when renewal is successful.
PauseAsync()
Pause the sandbox while preserving its state.
await sandbox.PauseAsync();
return
Task
Task that completes when sandbox is paused.
ResumeAsync()
Resume a previously paused sandbox.
var resumed = await sandbox.ResumeAsync();
return
Task<Sandbox>
Fresh, connected Sandbox instance.
KillAsync()
Terminate the remote sandbox instance.
await sandbox.KillAsync();
return
Task
Task that completes when sandbox is terminated.
DisposeAsync()
Close local resources associated with the sandbox.
await sandbox.DisposeAsync();
return
ValueTask
Task that completes when resources are closed.

Properties

Commands
Provides access to command execution operations.
var execution = await sandbox.Commands.RunAsync("echo 'Hello World'");
Console.WriteLine(execution.Logs.Stdout.FirstOrDefault()?.Text);
type
Commands
Command execution interface.
Files
Provides access to file system operations.
await sandbox.Files.WriteFilesAsync(new[]
{
    new WriteEntry { Path = "/tmp/hello.txt", Data = "Hello World", Mode = 644 }
});
var content = await sandbox.Files.ReadFileAsync("/tmp/hello.txt");
type
Filesystem
File system operations interface.

SandboxManager

Administrative interface for managing multiple sandbox instances.

Static Methods

Create()
Create a SandboxManager instance.
await using var manager = SandboxManager.Create(new SandboxManagerOptions
{
    ConnectionConfig = config
});
options
SandboxManagerOptions
required
return
SandboxManager
Configured sandbox manager instance.

Instance Methods

ListSandboxInfosAsync()
List sandboxes with filtering options.
var list = await manager.ListSandboxInfosAsync(new SandboxFilter
{
    States = new[] { SandboxStates.Running },
    PageSize = 10
});

foreach (var s in list.Items)
{
    Console.WriteLine(s.Id);
}
filter
SandboxFilter
required
return
Task<PagedSandboxInfos>
Paged sandbox information matching the filter criteria.
DisposeAsync()
Close local resources associated with the manager.
await manager.DisposeAsync();
return
ValueTask
Task that completes when resources are closed.

Service Interfaces

Commands

Command execution service for sandbox environments.

RunAsync()

Execute a shell command in the sandbox.
using OpenSandbox.Models;

// Simple execution
var execution = await sandbox.Commands.RunAsync("echo 'Hello World'");
Console.WriteLine(execution.Logs.Stdout.FirstOrDefault()?.Text);

// With streaming handlers
var handlers = new ExecutionHandlers
{
    OnStdout = msg => { Console.WriteLine($"STDOUT: {msg.Text}"); return Task.CompletedTask; },
    OnStderr = msg => { Console.Error.WriteLine($"STDERR: {msg.Text}"); return Task.CompletedTask; },
    OnExecutionComplete = c => { Console.WriteLine($"Finished in {c.ExecutionTimeMs}ms"); return Task.CompletedTask; },
};

await sandbox.Commands.RunAsync(
    "for i in 1 2 3; do echo \"Count $i\"; sleep 0.2; done",
    handlers: handlers
);
command
string
required
Shell command text to execute.
options
RunCommandOptions
handlers
ExecutionHandlers
Optional handlers for streaming events.
return
Task<Execution>
Execution handle representing the running command.

GetCommandStatusAsync()

Get the current running status for a command.
var status = await sandbox.Commands.GetCommandStatusAsync(execution.Id!);
Console.WriteLine($"running={status.Running}");
executionId
string
required
Unique identifier of the execution to query.
return
Task<CommandStatus>
CommandStatus describing running state and exit code.

GetBackgroundCommandLogsAsync()

Get background command logs (non-streamed).
var logs = await sandbox.Commands.GetBackgroundCommandLogsAsync(execution.Id!, cursor: 0);
Console.WriteLine($"cursor={logs.Cursor}");
executionId
string
required
Unique identifier of the execution to query.
cursor
int?
Optional line cursor for incremental reads.
return
Task<CommandLogs>
CommandLogs containing raw output and latest cursor.

Filesystem

Filesystem operations service for sandbox environments.

ReadFileAsync()

Read the content of a file as a string.
var content = await sandbox.Files.ReadFileAsync("/tmp/hello.txt");
Console.WriteLine($"Content: {content}");
path
string
required
The absolute or relative path to the file to read.
return
Task<string>
The file content as a string.

WriteFilesAsync()

Write content to files.
await sandbox.Files.WriteFilesAsync(new[]
{
    new WriteEntry { Path = "/tmp/hello.txt", Data = "Hello World", Mode = 644 }
});
entries
WriteEntry[]
required
List of write entries specifying files and their content.
return
Task
Task that completes when files are written.

CreateDirectoriesAsync()

Create directories.
await sandbox.Files.CreateDirectoriesAsync(new[]
{
    new CreateDirectoryEntry { Path = "/tmp/demo", Mode = 755 }
});
entries
CreateDirectoryEntry[]
required
List of directory entries.
return
Task
Task that completes when directories are created.

DeleteFilesAsync()

Delete the specified files.
await sandbox.Files.DeleteFilesAsync(new[] { "/tmp/hello.txt" });
paths
string[]
required
List of file paths to delete.
return
Task
Task that completes when files are deleted.

DeleteDirectoriesAsync()

Delete the specified directories.
await sandbox.Files.DeleteDirectoriesAsync(new[] { "/tmp/demo" });
paths
string[]
required
List of directory paths to delete.
return
Task
Task that completes when directories are deleted.

SearchAsync()

Search for files and directories.
var files = await sandbox.Files.SearchAsync(new SearchEntry { Path = "/tmp/demo", Pattern = "*.txt" });
foreach (var file in files)
{
    Console.WriteLine(file.Path);
}
entry
SearchEntry
required
return
Task<List<EntryInfo>>
List of matching file/directory information.

Configuration

ConnectionConfig

Connection configuration for API server communication.
using OpenSandbox.Config;

// Basic configuration
var config = new ConnectionConfig(new ConnectionConfigOptions
{
    Domain = "api.opensandbox.io",
    ApiKey = "your-key",
    RequestTimeoutSeconds = 60,
});

// Advanced: custom headers
var config2 = new ConnectionConfig(new ConnectionConfigOptions
{
    Domain = "api.opensandbox.io",
    ApiKey = "your-key",
    Headers = new Dictionary<string, string>
    {
        ["X-Custom-Header"] = "value"
    },
});
options
ConnectionConfigOptions
required

Diagnostics and Logging

The SDK uses Microsoft.Extensions.Logging abstractions.
using Microsoft.Extensions.Logging;
using OpenSandbox.Config;

using var loggerFactory = LoggerFactory.Create(builder =>
{
    builder.SetMinimumLevel(LogLevel.Debug);
    builder.AddConsole();
});

var sandbox = await Sandbox.CreateAsync(new SandboxCreateOptions
{
    Image = "python:3.11",
    ConnectionConfig = new ConnectionConfig(),
    Diagnostics = new SdkDiagnosticsOptions
    {
        LoggerFactory = loggerFactory
    }
});

Network Policy

var sandbox = await Sandbox.CreateAsync(new SandboxCreateOptions
{
    ConnectionConfig = config,
    Image = "python:3.11",
    NetworkPolicy = new NetworkPolicy
    {
        DefaultAction = NetworkRuleAction.Deny,
        Egress = new List<NetworkRule>
        {
            new() { Action = NetworkRuleAction.Allow, Target = "pypi.org" }
        }
    }
});

Exception Handling

The SDK throws SandboxException and derived exceptions for various error conditions.
try
{
    var execution = await sandbox.Commands.RunAsync("echo 'Hello Sandbox!'");
    Console.WriteLine(execution.Logs.Stdout.FirstOrDefault()?.Text);
}
catch (SandboxReadyTimeoutException)
{
    Console.Error.WriteLine("Sandbox did not become ready before the configured timeout.");
}
catch (SandboxApiException ex)
{
    Console.Error.WriteLine($"API Error: status={ex.StatusCode}, requestId={ex.RequestId}, message={ex.Message}");
}
catch (SandboxException ex)
{
    Console.Error.WriteLine($"Sandbox Error: [{ex.Error.Code}] {ex.Error.Message}");
}

Supported Frameworks

  • .NET Standard 2.0 (for maximum compatibility with .NET Framework 4.6.1+, .NET Core 2.0+, Mono, Xamarin, etc.)
  • .NET Standard 2.1
  • .NET 6.0 (LTS)
  • .NET 7.0
  • .NET 8.0 (LTS)
  • .NET 9.0
  • .NET 10.0

Complete Example

using OpenSandbox;
using OpenSandbox.Config;
using OpenSandbox.Core;
using OpenSandbox.Models;

var config = new ConnectionConfig(new ConnectionConfigOptions
{
    Domain = "api.opensandbox.io",
    ApiKey = "your-api-key",
});

try
{
    await using var sandbox = await Sandbox.CreateAsync(new SandboxCreateOptions
    {
        ConnectionConfig = config,
        Image = "python:3.11",
        TimeoutSeconds = 30 * 60,
    });

    // Write a file
    await sandbox.Files.WriteFilesAsync(new[]
    {
        new WriteEntry { Path = "/tmp/script.py", Data = "print('Hello World')", Mode = 644 }
    });

    // Execute command with streaming
    var handlers = new ExecutionHandlers
    {
        OnStdout = msg => { Console.WriteLine($"Output: {msg.Text}"); return Task.CompletedTask; }
    };
    await sandbox.Commands.RunAsync("python /tmp/script.py", handlers: handlers);

    // Get info
    var info = await sandbox.GetInfoAsync();
    Console.WriteLine($"State: {info.Status.State}");

    // Cleanup
    await sandbox.KillAsync();
}
catch (SandboxException ex)
{
    Console.Error.WriteLine($"Sandbox Error: [{ex.Error.Code}] {ex.Error.Message}");
}

Build docs developers (and LLMs) love