Class: Daytona::Process

Inherits:
Object
  • Object
show all
Includes:
Instrumentation
Defined in:
lib/daytona/process.rb

Overview

rubocop:disable Metrics/ClassLength

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Instrumentation

included

Constructor Details

#initialize(sandbox_id:, toolbox_api:, get_preview_link:, language: 'python', otel_state: nil) ⇒ Process

Initialize a new Process instance

Parameters:

  • sandbox_id (String)

    The ID of the Sandbox

  • toolbox_api (DaytonaToolboxApiClient::ProcessApi)

    API client for Sandbox operations

  • get_preview_link (Proc)

    Function to get preview link for a port

  • language (String) (defaults to: 'python')

    The language for code execution

  • otel_state (Daytona::OtelState, nil) (defaults to: nil)


31
32
33
34
35
36
37
# File 'lib/daytona/process.rb', line 31

def initialize(sandbox_id:, toolbox_api:, get_preview_link:, language: 'python', otel_state: nil)
  @sandbox_id = sandbox_id
  @toolbox_api = toolbox_api
  @get_preview_link = get_preview_link
  @language = language
  @otel_state = otel_state
end

Instance Attribute Details

Returns Function to get preview link for a port.

Returns:

  • (Proc)

    Function to get preview link for a port



19
20
21
# File 'lib/daytona/process.rb', line 19

def get_preview_link
  @get_preview_link
end

#languageString (readonly)

Returns The language for code execution (e.g. ‘python’, ‘typescript’, ‘javascript’).

Returns:

  • (String)

    The language for code execution (e.g. ‘python’, ‘typescript’, ‘javascript’)



22
23
24
# File 'lib/daytona/process.rb', line 22

def language
  @language
end

#sandbox_idString (readonly)

Returns The ID of the Sandbox.

Returns:

  • (String)

    The ID of the Sandbox



13
14
15
# File 'lib/daytona/process.rb', line 13

def sandbox_id
  @sandbox_id
end

#toolbox_apiDaytonaToolboxApiClient::ProcessApi (readonly)

Returns API client for Sandbox operations.

Returns:

  • (DaytonaToolboxApiClient::ProcessApi)

    API client for Sandbox operations



16
17
18
# File 'lib/daytona/process.rb', line 16

def toolbox_api
  @toolbox_api
end

Instance Method Details

#code_run(code:, params: nil, timeout: nil) ⇒ ExecuteResponse

Execute code in the Sandbox using the appropriate language runtime

Examples:

# Run Python code
response = sandbox.process.code_run(<<~CODE)
  x = 10
  y = 20
  print(f"Sum: {x + y}")
CODE
puts response.artifacts.stdout  # Prints: Sum: 30

Parameters:

  • code (String)

    Code to execute

  • params (CodeRunParams, nil) (defaults to: nil)

    Parameters for code execution

  • timeout (Integer, nil) (defaults to: nil)

    Maximum time in seconds to wait for the code to complete. 0 means wait indefinitely

Returns:

  • (ExecuteResponse)

    Code execution result containing exit_code, result, and artifacts



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/daytona/process.rb', line 86

def code_run(code:, params: nil, timeout: nil)
  response = toolbox_api.code_run(
    DaytonaToolboxApiClient::CodeRunRequest.new(
      code:, language:, argv: params&.argv, envs: params&.env, timeout:
    )
  )

  ExecuteResponse.new(
    exit_code: response.exit_code,
    result: response.result,
    artifacts: ExecutionArtifacts.new(response.result, (response.artifacts&.charts || []).map do |c|
      Charts.parse_chart(c)
    end)
  )
end

#connect_pty_session(session_id) ⇒ PtyHandle

Connects to an existing PTY session in the Sandbox.

Establishes a WebSocket connection to an existing PTY session, allowing you to interact with a previously created terminal session.

Examples:

# Connect to an existing PTY session
pty_handle = sandbox.process.connect_pty_session("my-pty-session")
pty_handle.wait_for_connection
pty_handle.send_input("echo 'Hello World'\n")
result = pty_handle.wait
pty_handle.disconnect

Parameters:

  • session_id (String)

    Unique identifier of the PTY session to connect to.

Returns:

  • (PtyHandle)

    Handle for managing the connected PTY session.

Raises:



445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
# File 'lib/daytona/process.rb', line 445

def connect_pty_session(session_id) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
  preview_link = get_preview_link.call(WS_PORT)
  url = URI.parse(preview_link.url)
  url.scheme = url.scheme == 'https' ? 'wss' : 'ws'
  url.path = "/process/pty/#{session_id}/connect"

  PtyHandle.new(
    WebSocket::Client::Simple.connect(
      url.to_s,
      headers: toolbox_api.api_client.default_headers.dup.merge(
        'X-Daytona-Preview-Token' => preview_link.token
      )
    ),
    session_id:,

    handle_resize: ->(pty_size) { resize_pty_session(session_id, pty_size) },
    handle_kill: -> { delete_pty_session(session_id) }
  ).tap(&:wait_for_connection)
end

#create_pty_session(id:, cwd: nil, envs: nil, pty_size: nil) ⇒ PtyHandle

Creates a new PTY (pseudo-terminal) session in the Sandbox.

Creates an interactive terminal session that can execute commands and handle user input. The PTY session behaves like a real terminal, supporting features like command history.

Examples:

# Create a basic PTY session
pty_handle = sandbox.process.create_pty_session(id: "my-pty")

# Create a PTY session with specific size and environment
pty_size = Daytona::PtySize.new(rows: 30, cols: 120)
pty_handle = sandbox.process.create_pty_session(
  id: "my-pty",
  cwd: "/workspace",
  envs: {"NODE_ENV" => "development"},
  pty_size: pty_size
)

# Use the PTY session
pty_handle.wait_for_connection
pty_handle.send_input("ls -la\n")
result = pty_handle.wait
pty_handle.disconnect

Parameters:

  • id (String)

    Unique identifier for the PTY session. Must be unique within the Sandbox.

  • cwd (String, nil) (defaults to: nil)

    Working directory for the PTY session. Defaults to the sandbox’s working directory.

  • envs (Hash<String, String>, nil) (defaults to: nil)

    Environment variables to set in the PTY session. These will be merged with the Sandbox’s default environment variables.

  • pty_size (PtySize, nil) (defaults to: nil)

    Terminal size configuration. Defaults to 80x24 if not specified.

Returns:

  • (PtyHandle)

    Handle for managing the created PTY session. Use this to send input, receive output, resize the terminal, and manage the session lifecycle.

Raises:

  • (Daytona::Sdk::Error)

    If the PTY session creation fails or the session ID is already in use.



413
414
415
416
417
418
419
420
421
422
423
424
425
426
# File 'lib/daytona/process.rb', line 413

def create_pty_session(id:, cwd: nil, envs: nil, pty_size: nil) # rubocop:disable Metrics/MethodLength
  response = toolbox_api.create_pty_session(
    DaytonaToolboxApiClient::PtyCreateRequest.new(
      id:,
      cwd:,
      envs:,
      cols: pty_size&.cols,
      rows: pty_size&.rows,
      lazy_start: true
    )
  )

  connect_pty_session(response.session_id)
end

#create_session(session_id) ⇒ void

This method returns an undefined value.

Creates a new long-running background session in the Sandbox

Sessions are background processes that maintain state between commands, making them ideal for scenarios requiring multiple related commands or persistent environment setup.

Examples:

# Create a new session
session_id = "my-session"
sandbox.process.create_session(session_id)
session = sandbox.process.get_session(session_id)
# Do work...
sandbox.process.delete_session(session_id)

Parameters:

  • session_id (String)

    Unique identifier for the new session



117
118
119
# File 'lib/daytona/process.rb', line 117

def create_session(session_id)
  toolbox_api.create_session(DaytonaToolboxApiClient::CreateSessionRequest.new(session_id:))
end

#delete_pty_session(session_id) ⇒ void

This method returns an undefined value.

Deletes a PTY session, terminating the associated process

Examples:

sandbox.process.delete_pty_session("my-pty")

Parameters:

  • session_id (String)

    Unique identifier of the PTY session to delete



492
493
494
# File 'lib/daytona/process.rb', line 492

def delete_pty_session(session_id)
  toolbox_api.delete_pty_session(session_id)
end

#delete_session(session_id) ⇒ Object

Terminates and removes a session from the Sandbox, cleaning up any resources associated with it

Examples:

# Create and use a session
sandbox.process.create_session("temp-session")
# ... use the session ...

# Clean up when done
sandbox.process.delete_session("temp-session")

Parameters:

  • session_id (String)

    Unique identifier of the session to delete



378
# File 'lib/daytona/process.rb', line 378

def delete_session(session_id) = toolbox_api.delete_session(session_id)

#exec(command:, cwd: nil, env: nil, timeout: nil) ⇒ ExecuteResponse

Execute a shell command in the Sandbox

Examples:

# Simple command
response = sandbox.process.exec("echo 'Hello'")
puts response.artifacts.stdout
=> "Hello\n"

# Command with working directory
result = sandbox.process.exec("ls", cwd: "workspace/src")

# Command with timeout
result = sandbox.process.exec("sleep 10", timeout: 5)

Parameters:

  • command (String)

    Shell command to execute

  • cwd (String, nil) (defaults to: nil)

    Working directory for command execution. If not specified, uses the sandbox working directory

  • env (Hash<String, String>, nil) (defaults to: nil)

    Environment variables to set for the command

  • timeout (Integer, nil) (defaults to: nil)

    Maximum time in seconds to wait for the command to complete.

Returns:

  • (ExecuteResponse)

    Command execution results containing exit_code, result, and artifacts



58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/daytona/process.rb', line 58

def exec(command:, cwd: nil, env: nil, timeout: nil)
  envs = env&.empty? ? nil : env

  response = toolbox_api.execute_command(DaytonaToolboxApiClient::ExecuteRequest.new(command:, cwd:, envs:,
                                                                                     timeout:))
  result = response.result || ''
  ExecuteResponse.new(
    exit_code: response.exit_code,
    result:,
    artifacts: ExecutionArtifacts.new(result, [])
  )
end

#execute_session_command(session_id:, req:) ⇒ Daytona::SessionExecuteResponse

Executes a command in the session

Examples:

# Execute commands in sequence, maintaining state
session_id = "my-session"

# Change directory
req = Daytona::SessionExecuteRequest.new(command: "cd /workspace")
sandbox.process.execute_session_command(session_id:, req:)

# Create a file
req = Daytona::SessionExecuteRequest.new(command: "echo 'Hello' > test.txt")
sandbox.process.execute_session_command(session_id:, req:)

# Read the file
req = Daytona::SessionExecuteRequest.new(command: "cat test.txt")
result = sandbox.process.execute_session_command(session_id:, req:)
puts "Command stdout: #{result.stdout}"
puts "Command stderr: #{result.stderr}"

Parameters:

  • session_id (String)

    Unique identifier of the session to use

  • req (Daytona::SessionExecuteRequest)

    Command execution request containing command and run_async

Returns:



182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
# File 'lib/daytona/process.rb', line 182

def execute_session_command(session_id:, req:) # rubocop:disable Metrics/MethodLength
  response = toolbox_api.session_execute_command(
    session_id,
    DaytonaToolboxApiClient::SessionExecuteRequest.new(command: req.command, run_async: req.run_async,
                                                       suppress_input_echo: req.suppress_input_echo)
  )

  SessionExecuteResponse.new(
    cmd_id: response.cmd_id,
    output: response.output,
    stdout: response.stdout || '',
    stderr: response.stderr || '',
    exit_code: response.exit_code,
    additional_properties: {}
  )
end

#get_entrypoint_logsDaytona::SessionCommandLogsResponse

Get the sandbox entrypoint logs

Examples:

logs = sandbox.process.get_entrypoint_logs()
puts "Command stdout: #{logs.stdout}"
puts "Command stderr: #{logs.stderr}"

Returns:



280
281
282
283
# File 'lib/daytona/process.rb', line 280

def get_entrypoint_logs
  response = toolbox_api.get_entrypoint_logs
  SessionCommandLogsResponse.new(output: response.output, stdout: response.stdout, stderr: response.stderr)
end

#get_entrypoint_logs_async(on_stdout:, on_stderr:) ⇒ WebSocket::Client::Simple::Client

Asynchronously retrieves and processes the sandbox entrypoint logs as they become available

Examples:

sandbox.process.get_entrypoint_logs_async(
  on_stdout: ->(log) { puts "[STDOUT]: #{log}" },
  on_stderr: ->(log) { puts "[STDERR]: #{log}" }
)

Parameters:

  • on_stdout (Proc)

    Callback function to handle stdout log chunks as they arrive

  • on_stderr (Proc)

    Callback function to handle stderr log chunks as they arrive

Returns:

  • (WebSocket::Client::Simple::Client)


296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
# File 'lib/daytona/process.rb', line 296

def get_entrypoint_logs_async(on_stdout:, on_stderr:) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
  preview_link = get_preview_link.call(WS_PORT)
  url = URI.parse(preview_link.url)
  url.scheme = url.scheme == 'https' ? 'wss' : 'ws'
  url.path = '/process/session/entrypoint/logs'
  url.query = 'follow=true'

  completion_queue = Queue.new

  ws = WebSocket::Client::Simple.connect(
    url.to_s,
    headers: toolbox_api.api_client.default_headers.dup.merge(
      'X-Daytona-Preview-Token' => preview_link.token,
      'Content-Type' => 'text/plain',
      'Accept' => 'text/plain'
    )
  )

  ws.on(:message) do |message|
    if message.type == :close
      ws.close
      completion_queue.push(:close)
    else
      stdout, stderr = Util.demux(message.data.to_s)

      on_stdout.call(stdout) unless stdout.empty?
      on_stderr.call(stderr) unless stderr.empty?
    end
  end

  ws.on(:close) do
    completion_queue.push(:close)
  end

  ws.on(:error) do |e|
    completion_queue.push(:error)
    raise Sdk::Error, "WebSocket error: #{e.message}"
  end

  # Wait for completion
  completion_queue.pop
end

#get_entrypoint_sessionDaytonaApiClient::Session

Gets the Sandbox entrypoint session

Examples:

session = sandbox.process.get_entrypoint_session()
session.commands.each do |cmd|
  puts "Command: #{cmd.command}"
end

Returns:

  • (DaytonaApiClient::Session)

    Entrypoint session information including session_id and commands



142
# File 'lib/daytona/process.rb', line 142

def get_entrypoint_session = toolbox_api.get_entrypoint_session

#get_pty_session_info(session_id) ⇒ DaytonaApiClient::PtySessionInfo

Gets detailed information about a specific PTY session

Retrieves comprehensive information about a PTY session including its current state, configuration, and metadata.

Examples:

# Get details about a specific PTY session
session_info = sandbox.process.get_pty_session_info("my-session")
puts "Session ID: #{session_info.id}"
puts "Active: #{session_info.active}"
puts "Working Directory: #{session_info.cwd}"
puts "Terminal Size: #{session_info.cols}x#{session_info.rows}"

Parameters:

  • session_id (String)

    Unique identifier of the PTY session to retrieve information for

Returns:

  • (DaytonaApiClient::PtySessionInfo)

    Detailed information about the PTY session including ID, state, creation time, working directory, environment variables, and more



528
529
530
# File 'lib/daytona/process.rb', line 528

def get_pty_session_info(session_id)
  toolbox_api.get_pty_session(session_id)
end

#get_session(session_id) ⇒ DaytonaApiClient::Session

Gets a session in the Sandbox

Examples:

session = sandbox.process.get_session("my-session")
session.commands.each do |cmd|
  puts "Command: #{cmd.command}"
end

Parameters:

  • session_id (String)

    Unique identifier of the session to retrieve

Returns:

  • (DaytonaApiClient::Session)

    Session information including session_id and commands



131
# File 'lib/daytona/process.rb', line 131

def get_session(session_id) = toolbox_api.get_session(session_id)

#get_session_command(session_id:, command_id:) ⇒ DaytonaApiClient::Command

Gets information about a specific command executed in a session

Examples:

cmd = sandbox.process.get_session_command(session_id: "my-session", command_id: "cmd-123")
if cmd.exit_code == 0
  puts "Command #{cmd.command} completed successfully"
end

Parameters:

  • session_id (String)

    Unique identifier of the session

  • command_id (String)

    Unique identifier of the command

Returns:

  • (DaytonaApiClient::Command)

    Command information including id, command, and exit_code



155
156
157
# File 'lib/daytona/process.rb', line 155

def get_session_command(session_id:, command_id:)
  toolbox_api.get_session_command(session_id, command_id)
end

#get_session_command_logs(session_id:, command_id:) ⇒ Daytona::SessionCommandLogsResponse

Get the logs for a command executed in a session

Examples:

logs = sandbox.process.get_session_command_logs(session_id: "my-session", command_id: "cmd-123")
puts "Command stdout: #{logs.stdout}"
puts "Command stderr: #{logs.stderr}"

Parameters:

  • session_id (String)

    Unique identifier of the session

  • command_id (String)

    Unique identifier of the command

Returns:



209
210
211
212
# File 'lib/daytona/process.rb', line 209

def get_session_command_logs(session_id:, command_id:)
  response = toolbox_api.get_session_command_logs(session_id, command_id)
  SessionCommandLogsResponse.new(output: response.output, stdout: response.stdout, stderr: response.stderr)
end

#get_session_command_logs_async(session_id:, command_id:, on_stdout:, on_stderr:) ⇒ WebSocket::Client::Simple::Client

Asynchronously retrieves and processes the logs for a command executed in a session as they become available

Examples:

sandbox.process.get_session_command_logs_async(
  session_id: "my-session",
  command_id: "cmd-123",
  on_stdout: ->(log) { puts "[STDOUT]: #{log}" },
  on_stderr: ->(log) { puts "[STDERR]: #{log}" }
)

Parameters:

  • session_id (String)

    Unique identifier of the session

  • command_id (String)

    Unique identifier of the command

  • on_stdout (Proc)

    Callback function to handle stdout log chunks as they arrive

  • on_stderr (Proc)

    Callback function to handle stderr log chunks as they arrive

Returns:

  • (WebSocket::Client::Simple::Client)


229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
# File 'lib/daytona/process.rb', line 229

def get_session_command_logs_async(session_id:, command_id:, on_stdout:, on_stderr:) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
  preview_link = get_preview_link.call(WS_PORT)
  url = URI.parse(preview_link.url)
  url.scheme = url.scheme == 'https' ? 'wss' : 'ws'
  url.path = "/process/session/#{session_id}/command/#{command_id}/logs"
  url.query = 'follow=true'

  completion_queue = Queue.new

  ws = WebSocket::Client::Simple.connect(
    url.to_s,
    headers: toolbox_api.api_client.default_headers.dup.merge(
      'X-Daytona-Preview-Token' => preview_link.token,
      'Content-Type' => 'text/plain',
      'Accept' => 'text/plain'
    )
  )

  ws.on(:message) do |message|
    if message.type == :close
      ws.close
      completion_queue.push(:close)
    else
      stdout, stderr = Util.demux(message.data.to_s)

      on_stdout.call(stdout) unless stdout.empty?
      on_stderr.call(stderr) unless stderr.empty?
    end
  end

  ws.on(:close) do
    completion_queue.push(:close)
  end

  ws.on(:error) do |e|
    completion_queue.push(:error)
    raise Sdk::Error, "WebSocket error: #{e.message}"
  end

  # Wait for completion
  completion_queue.pop
end

#list_pty_sessionsArray<DaytonaApiClient::PtySessionInfo>

Lists all PTY sessions in the Sandbox

Examples:

sessions = sandbox.process.list_pty_sessions
sessions.each do |session|
  puts "PTY Session #{session.id}: #{session.cols}x#{session.rows}"
end

Returns:

  • (Array<DaytonaApiClient::PtySessionInfo>)

    List of PTY session information



505
506
507
508
509
510
# File 'lib/daytona/process.rb', line 505

def list_pty_sessions
  response = toolbox_api.list_pty_sessions
  return [] if response.nil?

  response.respond_to?(:sessions) ? (response.sessions || []) : response
end

#list_sessionsArray<DaytonaApiClient::Session>

Returns List of all sessions in the Sandbox.

Examples:

sessions = sandbox.process.list_sessions
sessions.each do |session|
  puts "Session #{session.session_id}:"
  puts "  Commands: #{session.commands.length}"
end

Returns:

  • (Array<DaytonaApiClient::Session>)

    List of all sessions in the Sandbox



365
# File 'lib/daytona/process.rb', line 365

def list_sessions = toolbox_api.list_sessions

#resize_pty_session(session_id, pty_size) ⇒ DaytonaApiClient::PtySessionInfo

Resizes a PTY session to the specified dimensions

Examples:

pty_size = Daytona::PtySize.new(rows: 30, cols: 120)
session_info = sandbox.process.resize_pty_session("my-pty", pty_size)
puts "PTY resized to #{session_info.cols}x#{session_info.rows}"

Parameters:

  • session_id (String)

    Unique identifier of the PTY session

  • pty_size (PtySize)

    New terminal size

Returns:

  • (DaytonaApiClient::PtySessionInfo)

    Updated PTY session information



475
476
477
478
479
480
481
482
483
# File 'lib/daytona/process.rb', line 475

def resize_pty_session(session_id, pty_size)
  toolbox_api.resize_pty_session(
    session_id,
    DaytonaToolboxApiClient::PtyResizeRequest.new(
      cols: pty_size.cols,
      rows: pty_size.rows
    )
  )
end

#send_session_command_input(session_id:, command_id:, data:) ⇒ void

This method returns an undefined value.

Sends input data to a command executed in a session

This method allows you to send input to an interactive command running in a session, such as responding to prompts or providing data to stdin.

Parameters:

  • session_id (String)

    Unique identifier of the session

  • command_id (String)

    Unique identifier of the command

  • data (String)

    Input data to send to the command



348
349
350
351
352
353
354
# File 'lib/daytona/process.rb', line 348

def send_session_command_input(session_id:, command_id:, data:)
  toolbox_api.send_input(
    session_id,
    command_id,
    DaytonaToolboxApiClient::SessionSendInputRequest.new(data:)
  )
end