Documentation Index Fetch the complete documentation index at: https://mintlify.com/brimblehq/rexec/llms.txt
Use this file to discover all available pages before exploring further.
.NET SDK
The official .NET SDK for Rexec provides a modern, cross-platform interface for Terminal as a Service.
Requirements
Installation
.NET CLI
Package Manager
PackageReference
Quick Start
using Rexec ;
// Create client
var client = new RexecClient ( "https://your-instance.com" , "your-api-token" );
// Create a container
var container = await client . Containers . CreateAsync ( "ubuntu:24.04" );
Console . WriteLine ( $"Created: { container . Id } " );
// Start it
await client . Containers . StartAsync ( container . Id );
// Execute a command
var result = await client . Containers . ExecAsync ( container . Id , "echo 'Hello from .NET!'" );
Console . WriteLine ( result . Stdout );
// Clean up
await client . Containers . DeleteAsync ( container . Id );
Client Initialization
Basic Client
using Rexec ;
var client = new RexecClient (
"https://your-instance.com" ,
"your-api-token"
);
The RexecClient class is defined at /home/daytona/workspace/source/sdk/dotnet/RexecClient.cs:18.
With Dependency Injection
using Microsoft . Extensions . DependencyInjection ;
using Rexec ;
services . AddSingleton < RexecClient >( sp =>
new RexecClient (
"https://your-instance.com" ,
"your-api-token"
)
);
With Disposal
using var client = new RexecClient ( baseUrl , token );
// Client is automatically disposed
Container Operations
The Container service provides methods for managing sandboxed environments.
List Containers
var containers = await client . Containers . ListAsync ();
foreach ( var c in containers )
{
Console . WriteLine ( $" { c . Name } : { c . Status } " );
}
Get Container
var container = await client . Containers . GetAsync ( containerId );
Console . WriteLine ( $"Container { container . Name } is { container . Status } " );
Create Container
// Simple creation
var container = await client . Containers . CreateAsync ( "ubuntu:24.04" );
// With options using fluent API
var container = await client . Containers . CreateAsync (
new CreateContainerRequest ( "python:3.12" )
. WithName ( "my-python-sandbox" )
. WithEnv ( "PYTHONPATH" , "/app" )
. WithEnv ( "DEBUG" , "true" )
. WithLabel ( "project" , "demo" )
);
Console . WriteLine ( $"Created: { container . Id } " );
Start Container
await client . Containers . StartAsync ( containerId );
Stop Container
await client . Containers . StopAsync ( containerId );
Delete Container
await client . Containers . DeleteAsync ( containerId );
Execute Commands
var result = await client . Containers . ExecAsync (
containerId ,
"python --version"
);
if ( result . IsSuccess )
{
Console . WriteLine ( result . Stdout );
}
else
{
Console . WriteLine ( $"Error: { result . Stderr } " );
}
File Operations
Manage files and directories within containers.
List Files
var files = await client . Files . ListAsync ( containerId , "/app" );
foreach ( var file in files )
{
var type = file . IsDir ? "DIR" : $" { file . Size } bytes" ;
Console . WriteLine ( $" { file . Name } - { type } " );
}
Read File
var content = await client . Files . ReadStringAsync ( containerId , "/etc/hostname" );
Console . WriteLine ( $"Hostname: { content } " );
// Or read as bytes
var bytes = await client . Files . ReadBytesAsync ( containerId , "/path/to/file" );
Write File
await client . Files . WriteAsync (
containerId ,
"/app/script.py" ,
"print('Hello!')"
);
// Or write bytes
await client . Files . WriteBytesAsync (
containerId ,
"/path/to/file" ,
byteArray
);
Delete File
await client . Files . DeleteAsync ( containerId , "/tmp/scratch.txt" );
Interactive Terminal
Connect to containers via WebSocket for real-time terminal access.
Basic Terminal Usage
await using var terminal = await client . Terminal . ConnectAsync ( containerId );
// Set up event handlers
terminal . OnData += data => Console . Write ( data );
terminal . OnClose += () => Console . WriteLine ( "Disconnected" );
terminal . OnError += ex => Console . WriteLine ( $"Error: { ex . Message } " );
// Send commands
await terminal . WriteAsync ( "ls -la \n " );
await terminal . WriteAsync ( "cd /app && python main.py \n " );
// Resize terminal
await terminal . ResizeAsync ( 120 , 40 );
// The using statement handles cleanup automatically
Terminal with Custom Size
await using var terminal = await client . Terminal . ConnectAsync (
containerId ,
cols : 120 ,
rows : 40
);
Advanced Examples
Run Script and Capture Output
async Task < string > RunScriptAsync (
RexecClient client ,
string containerId ,
string script )
{
var output = new StringBuilder ();
await using var terminal = await client . Terminal . ConnectAsync ( containerId );
terminal . OnData += data => output . Append ( data );
var tcs = new TaskCompletionSource < bool >();
terminal . OnClose += () => tcs . SetResult ( true );
await terminal . WriteAsync ( $" { script } \n exit \n " );
await tcs . Task ;
return output . ToString ();
}
// Usage
var result = await RunScriptAsync (
client ,
container . Id ,
"apt update && apt install -y curl"
);
Console . WriteLine ( result );
Parallel Container Creation
async Task < List < Container >> CreateBatchAsync (
RexecClient client ,
int count )
{
var tasks = Enumerable . Range ( 0 , count )
. Select ( i => client . Containers . CreateAsync (
new CreateContainerRequest ( "ubuntu:24.04" )
. WithName ( $"worker- { i } " )
));
return ( await Task . WhenAll ( tasks )). ToList ();
}
// Create 5 containers in parallel
var containers = await CreateBatchAsync ( client , 5 );
Console . WriteLine ( $"Created { containers . Count } containers" );
File Upload
async Task UploadFileAsync (
RexecClient client ,
string containerId ,
string localPath ,
string remotePath )
{
var content = await File . ReadAllTextAsync ( localPath );
await client . Files . WriteAsync ( containerId , remotePath , content );
}
// Usage
await UploadFileAsync (
client ,
container . Id ,
"./local-script.sh" ,
"/home/script.sh"
);
Directory Sync
async Task SyncDirectoryAsync (
RexecClient client ,
string containerId ,
string localDir ,
string remoteDir )
{
await client . Files . MkdirAsync ( containerId , remoteDir );
var files = Directory . GetFiles ( localDir , "*" , SearchOption . AllDirectories );
foreach ( var file in files )
{
var relativePath = Path . GetRelativePath ( localDir , file );
var remotePath = Path . Combine ( remoteDir , relativePath )
. Replace ( " \\ " , "/" );
var content = await File . ReadAllBytesAsync ( file );
await client . Files . WriteBytesAsync ( containerId , remotePath , content );
Console . WriteLine ( $"Uploaded: { remotePath } " );
}
}
Real-time Log Streaming
async Task StreamLogsAsync (
RexecClient client ,
string containerId ,
string command ,
CancellationToken cancellationToken = default )
{
await using var terminal = await client . Terminal . ConnectAsync ( containerId );
terminal . OnData += data =>
{
Console . Write ( data );
// Could also save to file
// File.AppendAllText("logs.txt", data);
};
await terminal . WriteAsync ( $" { command } \n " );
// Keep connection open until cancelled
await Task . Delay ( Timeout . Infinite , cancellationToken );
}
// Usage with cancellation
using var cts = new CancellationTokenSource ();
var task = StreamLogsAsync ( client , container . Id , "tail -f /var/log/app.log" , cts . Token );
// Cancel after 30 seconds
cts . CancelAfter ( TimeSpan . FromSeconds ( 30 ));
await task ;
Error Handling
using Rexec ;
try
{
var container = await client . Containers . GetAsync ( "invalid-id" );
}
catch ( RexecException ex ) when ( ex . IsApiError )
{
Console . WriteLine ( $"API error { ex . StatusCode } : { ex . Message } " );
}
catch ( RexecException ex )
{
Console . WriteLine ( $"Network error: { ex . Message } " );
}
catch ( Exception ex )
{
Console . WriteLine ( $"Unexpected error: { ex . Message } " );
}
Async/Await and Cancellation
All methods support cancellation tokens:
using var cts = new CancellationTokenSource ( TimeSpan . FromSeconds ( 30 ));
try
{
var containers = await client . Containers . ListAsync ( cts . Token );
}
catch ( OperationCanceledException )
{
Console . WriteLine ( "Operation timed out" );
}
LINQ Integration
Use LINQ with SDK results:
var containers = await client . Containers . ListAsync ();
// Filter containers
var running = containers
. Where ( c => c . Status == "running" )
. ToList ();
// Group by image
var grouped = containers
. GroupBy ( c => c . Image )
. Select ( g => new { Image = g . Key , Count = g . Count () });
// Order by creation time
var sorted = containers
. OrderByDescending ( c => c . CreatedAt );
Dependency Injection Example
using Microsoft . Extensions . DependencyInjection ;
using Microsoft . Extensions . Hosting ;
using Rexec ;
var builder = Host . CreateApplicationBuilder ( args );
// Register RexecClient
builder . Services . AddSingleton < RexecClient >( sp =>
new RexecClient (
builder . Configuration [ "Rexec:BaseUrl" ],
builder . Configuration [ "Rexec:Token" ]
)
);
// Register your services
builder . Services . AddScoped < IContainerService , ContainerService >();
var host = builder . Build ();
await host . RunAsync ();
Source Code
View the full source code on GitHub:
License
MIT License - see LICENSE for details.