Skip to content

Pseudo Terminal (PTY)

The Daytona SDK provides powerful pseudo terminal (PTY) capabilities through the process module in Sandboxes. PTY sessions allow you to create interactive terminal sessions that can execute commands, handle user input, and manage terminal operations.

What is PTY?

A PTY (Pseudo Terminal) is a virtual terminal interface that allows programs to interact with a shell as if they were connected to a real terminal. PTY sessions in Daytona enable:

  • Interactive command execution with real-time input/output
  • Terminal resizing capabilities
  • Process management with kill operations
  • Real-time data streaming from terminal sessions

Interactive Commands with PTY

PTY sessions excel at handling interactive commands that require user input and can be resized during execution.

import time
from daytona import Daytona, Sandbox
from daytona.common.pty import PtySize
def handle_pty_data(data: bytes):
text = data.decode("utf-8", errors="replace")
print(text, end="")
# Create PTY session
pty_handle = sandbox.process.create_pty_session(
id="interactive-session",
pty_size=PtySize(cols=300, rows=100)
)
# Send interactive command
pty_handle.send_input('printf "Are you accepting the terms and conditions? (y/n): " && read confirm && if [ "$confirm" = "y" ]; then echo "You accepted"; else echo "You did not accept"; fi\n')
time.sleep(1)
pty_handle.send_input("y\n")
# Resize terminal
pty_session_info = pty_handle.resize(PtySize(cols=210, rows=110))
print(f"PTY session resized to {pty_session_info.cols}x{pty_session_info.rows}")
# Exit the session
pty_handle.send_input('exit\n')
# Handle output using iterator
for data in pty_handle:
handle_pty_data(data)
print(f"Session completed with exit code: {pty_handle.exit_code}")

Long-Running Processes with PTY

PTY sessions are perfect for managing long-running processes that need to be monitored or terminated.

import time
from daytona import Daytona, Sandbox
from daytona.common.pty import PtySize
def handle_pty_data(data: bytes):
text = data.decode("utf-8", errors="replace")
print(text, end="")
# Create PTY session
pty_handle = sandbox.process.create_pty_session(
id="long-running-session",
pty_size=PtySize(cols=120, rows=30)
)
# Start a long-running process
pty_handle.send_input('while true; do echo "Running... $(date)"; sleep 1; done\n')
# Using thread and wait() method to handle PTY output
thread = threading.Thread(target=pty_handle.wait, args=(handle_pty_data, 10))
thread.start()
time.sleep(3) # Let it run for a bit
print("Killing long-running process...")
pty_handle.kill()
thread.join()
print(f"\nProcess terminated with exit code: {result.exit_code}")
if result.error:
print(f"Termination reason: {result.error}")

Best Practices

Resource Management

Always clean up PTY sessions to prevent resource leaks:

# Python: Use try/finally
pty_handle = None
try:
pty_handle = sandbox.process.create_pty_session(id="session", pty_size=PtySize(cols=120, rows=30))
# Do work...
finally:
if pty_handle:
pty_handle.kill()

Error Handling

Monitor exit codes and handle errors appropriately:

# Python: Check exit codes
result = pty_handle.wait()
if result.exit_code != 0:
print(f"Command failed: {result.exit_code}")
print(f"Error: {result.error}")

Common Use Cases

  • Interactive Development: REPLs, debuggers, and development tools
  • Build Processes: Running and monitoring compilation, testing, or deployment
  • System Administration: Remote server management and configuration
  • User Interfaces: Terminal-based applications requiring user interaction

Troubleshooting

Connection Issues: Verify sandbox status, network connectivity, and proper session IDs. Performance Issues: Use appropriate terminal dimensions and efficient data handlers. Process Management: Use explicit kill() calls and proper timeout handling for long-running processes.