Hopx Cloud Sandboxes

repository·main·Indexed 43 days ago

https://github.com/hopx-ai/hopx

Secure, isolated, and lightweight cloud VM sandboxes designed for AI agents to execute code safely. Hopx provides a CLI (v0.1.2) and a JavaScript/TypeScript SDK (@hopx-ai/sdk) to manage sandbox lifecycles, execute code in multiple languages (Python, JavaScript, Bash, Go, Rust, Java), manage files, and configure environment variables.

Tokens
75.3K
Snippets
284
Records
347
Agent score
55%

What's inside Hopx

  1. How WebSocket authentication works in the Python SDK

    main

    Starting from version 0.3.3, the Hopx Python SDK requires JWT authentication for WebSocket connections. The Sandbox object manages the lifecycle of the JWT token and automatically passes it to the WebSocketClient. When a token is refreshed, the Sandbox calls update_jwt_token() on the client to ensure subsequent connections use the valid credentials.

    Key components involved in the authentication flow:

    • Sandbox: Retrieves the token via get_token() and initializes the WebSocketClient with it.
    • WebSocketClient: Stores the _jwt_token and includes it in the Authorization: Bearer <token> header during the websockets.connect() call.
    • AsyncTerminal: Retrieves the token from the sandbox to authenticate terminal WebSocket connections.
    # Conceptual flow of token passing in Sandbox
    token = self.get_token()
    self._ws_client = WebSocketClient(agent_url, token)
    
    # On token refresh
    if "auth_token" in response:
        self._ws_client.update_jwt_token(response["auth_token"])
  2. Create custom sandbox templates

    main

    Hopx provides public templates like code-interpreter (data science focused) and base (minimal Ubuntu). You can build custom reusable templates using the Template class to define images, file copies, commands, and working directories.

    import { Template, waitForPort } from '@hopx-ai/sdk';
    
    const template = new Template()
      .fromNodeImage('20')
      .copy('package.json', '/app/package.json')
      .copy('src/', '/app/src/')
      .runCmd('cd /app && npm install')
      .setWorkdir('/app')
      .setStartCmd('node src/index.js', waitForPort(3000));
    
    const result = await Template.build(template, {
      name: 'my-app',
      apiKey: 'your-api-key'
    });
    
    const sandbox = await Sandbox.create({ templateId: result.templateID });
  3. Migrate Private Registry Authentication methods

    main

    Methods for authenticating with private registries have been renamed to clarify their purpose. Use fromPrivateImage instead of fromImage when providing credentials, and use the updated GCP/AWS specific methods.

    ```typescript
    // ✅ After
    template.fromPrivateImage('registry.example.com/myimage:tag', {
      username: 'user',
      password: 'pass'
    });
    # ✅ After
    template.from_private_image('registry.example.com/myimage:tag', RegistryAuth(
        username='user',
        password='pass'
    ))

    Renamed Cloud Registry Methods:

    • fromGCPRegistry() → fromGCPPrivateImage()
    • fromAWSRegistry() → fromAWSPrivateImage()
    • from_gcp_registry() → from_gcp_private_image()
    • from_aws_registry() → from_aws_private_image()
  4. Migrate Template base image specification

    main

    The FROM step type has been removed. You must now specify base images using either the Template constructor or specific helper methods like fromPythonImage() (JS/TS) or from_python_image() (Python).

    // ✅ After - Base image in constructor
    const template = new Template('python:3.11')
      .runCmd('pip install numpy');
    
    // Or using helper methods
    const template = new Template()
      .fromPythonImage('3.11')
      .runCmd('pip install numpy');
    # ✅ After - Base image in constructor
    template = Template(from_image='python:3.11').run_cmd('pip install numpy')
    
    # Or using helper methods
    template = Template().from_python_image('3.11').run_cmd('pip install numpy')
  5. Set up the JavaScript/TypeScript SDK for testing

    main

    To run the template building tests for the JavaScript/TypeScript SDK, you must first install the dependencies and build the SDK from the javascript/ directory.

    Prerequisites

    1. Navigate to the javascript/ directory.
    2. Install npm dependencies.
    3. Build the SDK.
    cd javascript/
    
    # Install dependencies
    npm install
    
    # Build the SDK
    npm run build
    cd javascript/
    npm install
    npm run build
  6. Run WebSocket authentication tests

    main

    To verify that WebSocket authentication and error handling are working correctly in your environment, you can run the comprehensive test suite provided in the examples directory. This requires a valid Hopx API key.

    Prerequisites:

    • Python 3.8+
    • websockets library >= 12.0
    • A valid HOPX_API_KEY environment variable.

    Execution:

    export HOPX_API_KEY="your_api_key"
    python examples/test_websocket_auth.py
  7. Scripting with Hopx CLI exit codes and JSON

    main

    The Hopx CLI is designed for shell scripting. It supports JSON output for easy parsing and provides specific exit codes for error handling.

    Output Formats:

    • table (default): Human-readable tables.
    • json: Machine-readable JSON (recommended for scripts).
    • plain: Simple plain text.

    Example: Parsing JSON with jq

    # Get sandbox ID from creation command
    SANDBOX_ID=$(hopx sandbox create -t python -o json | jq -r '.sandbox_id')
    
    # List running sandboxes
    hopx sandbox list --status running -o json | jq '.[] | .sandbox_id'

    Exit Codes:

    CodeMeaning
    0Success
    1General error
    2Validation error
    3Authentication error
    4Not found
    5Timeout
    6Network error
    7Rate limit
    130Interrupted (Ctrl+C)

    Example: Conditional Logic in Bash

    hopx sandbox create --template python
    case $? in
        0) echo "Success" ;;
        3) echo "Authentication failed - check API key" ;;
        4) echo "Template not found" ;;
        7) echo "Rate limit exceeded - wait and retry" ;;
        *) echo "Error occurred" ;;
    esac
    # Get sandbox ID from JSON output
    SANDBOX_ID=$(hopx sandbox create -t python -o json | jq -r '.sandbox_id')
  8. Install the Hopx CLI

    main

    You can install the Hopx CLI using a one-line installer that automatically detects your OS and Python version.

    Quick Install

    curl -fsSL https://get.hopx.ai/install.sh | bash

    Installation Modes

    If you are running the script locally or want to specify a method, use the --mode flag:

    • pip (Default): Standard installation via pip.
    • pipx: Installs the CLI in an isolated environment.
    • git: Installs the development version directly from GitHub.

    Environment Variables

    • HOPX_INSTALL_MODE: Set to pip, pipx, or git to control the installation method.
    • HOPX_DRY_RUN: Set to true to perform a dry run without making any changes.

    Post-Installation Verification

    After installation, verify it works by running:

    hopx --version
    hopx --help
    hopx run "print('Hello from Hopx!')"
  9. Quick Start with Hopx Sandbox

    main

    To get started, import Sandbox from @hopx-ai/sdk and use Sandbox.create() to initialize a new environment. You can specify a template (like code-interpreter) and provide an apiKey. You can also use the HOPX_API_KEY environment variable instead of passing it explicitly. Once created, use runCode() to execute scripts and kill() to destroy the sandbox and stop billing.

    import { Sandbox } from '@hopx-ai/sdk';
    
    const sandbox = await Sandbox.create({
      template: 'code-interpreter',
      apiKey: 'your-api-key'  // or set HOPX_API_KEY environment variable
    });
    
    const result = await sandbox.runCode(`
    console.log('Node.js', process.version);
    console.log('Hello from Hopx!');
    `);
    
    console.log(result.stdout);
    await sandbox.kill();