> ## Documentation Index
> Fetch the complete documentation index at: https://docs.hopx.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Downloading

> Download files from sandboxes to your local filesystem. Retrieve files from HopX sandboxes to your local machine for further processing, analysis, or storage. Learn how to download single files or bulk download multiple files using Python and JavaScript SDKs or REST API. Includes examples for file downloads and progress tracking.

Download files from sandboxes to your local filesystem. This is useful for retrieving generated outputs, results, plots, or any files created in your sandbox.

## Overview

File downloading is essential for:

* Retrieving generated outputs and results
* Saving plots and visualizations
* Downloading processed data files
* Archiving sandbox contents

<Note>
  Download supports both text and binary files. Large files may take longer to download - set appropriate timeouts for large transfers.
</Note>

## Basic Download

Download a file from sandbox to local:

<Tabs>
  <Tab title="Python">
    ```python theme={null}
    from hopx_ai import Sandbox

    sandbox = Sandbox.create(template="code-interpreter")

    # Create a file in sandbox
    sandbox.files.write('/workspace/output.txt', 'Hello from sandbox!')

    # Download to local filesystem
    sandbox.files.download('/workspace/output.txt', './downloaded_output.txt')
    print("File downloaded successfully")

    # Verify download
    with open('./downloaded_output.txt', 'r') as f:
        content = f.read()
        print(f"Downloaded content: {content}")

    sandbox.kill()
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    import { Sandbox } from '@hopx-ai/sdk';
    import * as fs from 'fs';

    const sandbox = await Sandbox.create({ template: 'code-interpreter' });

    // Create a file in sandbox
    await sandbox.files.write('/workspace/output.txt', 'Hello from sandbox!');

    // Download to local filesystem
    const content = await sandbox.files.download('/workspace/output.txt');
    fs.writeFileSync('./downloaded_output.txt', content);
    console.log('File downloaded successfully');

    // Verify download
    const downloadedContent = fs.readFileSync('./downloaded_output.txt', 'utf-8');
    console.log(`Downloaded content: ${downloadedContent}`);

    await sandbox.kill();
    ```
  </Tab>
</Tabs>

## Download with Timeout

Set timeout for large file downloads:

<Tabs>
  <Tab title="Python">
    ```python theme={null}
    from hopx_ai import Sandbox

    sandbox = Sandbox.create(template="code-interpreter")

    # Generate a large file
    sandbox.run_code('''
    with open('/workspace/large_data.txt', 'w') as f:
        f.write('x' * 1000000)  # 1MB
    ''')

    # Download with extended timeout
    sandbox.files.download('/workspace/large_data.txt', './large_data.txt', timeout=300)
    print("Large file downloaded")

    # Verify
    import os
    file_size = os.path.getsize('./large_data.txt') / 1024 / 1024
    print(f"Downloaded file size: {file_size:.2f} MB")

    sandbox.kill()
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    import { Sandbox } from '@hopx-ai/sdk';
    import * as fs from 'fs';

    const sandbox = await Sandbox.create({ template: 'code-interpreter' });

    // Generate a large file
    await sandbox.runCode(`
    with open('/workspace/large_data.txt', 'w') as f:
        f.write('x' * 1000000)  # 1MB
    `);

    // Download
    const content = await sandbox.files.download('/workspace/large_data.txt');
    fs.writeFileSync('./large_data.txt', content);
    console.log('Large file downloaded');

    // Verify
    const stats = fs.statSync('./large_data.txt');
    const fileSize = stats.size / 1024 / 1024;
    console.log(`Downloaded file size: ${fileSize.toFixed(2)} MB`);

    await sandbox.kill();
    ```
  </Tab>
</Tabs>

## Download Binary Files

Download binary files (images, PDFs, etc.):

<Tabs>
  <Tab title="Python">
    ```python theme={null}
    from hopx_ai import Sandbox

    sandbox = Sandbox.create(template="code-interpreter")

    # Generate a plot
    sandbox.run_code('''
    import matplotlib.pyplot as plt
    plt.plot([1, 2, 3, 4])
    plt.savefig('/workspace/plot.png')
    ''')

    # Download the image
    sandbox.files.download('/workspace/plot.png', './local_plot.png')
    print("Plot downloaded")

    # Verify it's a valid image
    with open('./local_plot.png', 'rb') as f:
        header = f.read(8)
        print(f"PNG header: {header[:8]}")  # Should start with PNG signature

    sandbox.kill()
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    import { Sandbox } from '@hopx-ai/sdk';
    import * as fs from 'fs';

    const sandbox = await Sandbox.create({ template: 'code-interpreter' });

    // Generate a plot
    await sandbox.runCode(`
    import matplotlib.pyplot as plt
    plt.plot([1, 2, 3, 4])
    plt.savefig('/workspace/plot.png')
    `);

    // Download the image
    const imageData = await sandbox.files.download('/workspace/plot.png');
    fs.writeFileSync('./local_plot.png', imageData);
    console.log('Plot downloaded');

    // Verify it's a valid image
    const buffer = fs.readFileSync('./local_plot.png');
    console.log(`PNG header: ${buffer.slice(0, 8)}`);  // Should start with PNG signature

    await sandbox.kill();
    ```
  </Tab>
</Tabs>

## Download Multiple Files

Download multiple files:

<Tabs>
  <Tab title="Python">
    ```python theme={null}
    from hopx_ai import Sandbox
    import os

    sandbox = Sandbox.create(template="code-interpreter")

    # Generate multiple files
    sandbox.run_code('''
    import json
    import matplotlib.pyplot as plt

    # Create data file
    with open('/workspace/data.json', 'w') as f:
        json.dump({"values": [1, 2, 3]}, f)

    # Create plot
    plt.plot([1, 2, 3])
    plt.savefig('/workspace/plot.png')

    # Create text file
    with open('/workspace/readme.txt', 'w') as f:
        f.write("Generated files")
    ''')

    # Download all files
    files_to_download = [
        ('/workspace/data.json', './downloaded_data.json'),
        ('/workspace/plot.png', './downloaded_plot.png'),
        ('/workspace/readme.txt', './downloaded_readme.txt')
    ]

    print("📥 Downloading files...")
    for remote_path, local_path in files_to_download:
        try:
            sandbox.files.download(remote_path, local_path)
            file_size = os.path.getsize(local_path) / 1024
            print(f"  ✅ {remote_path} → {local_path} ({file_size:.2f} KB)")
        except Exception as e:
            print(f"  ❌ Failed to download {remote_path}: {e}")

    sandbox.kill()
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    import { Sandbox } from '@hopx-ai/sdk';
    import * as fs from 'fs';

    const sandbox = await Sandbox.create({ template: 'code-interpreter' });

    // Generate multiple files
    await sandbox.runCode(`
    import json
    import matplotlib.pyplot as plt

    # Create data file
    with open('/workspace/data.json', 'w') as f:
        json.dump({"values": [1, 2, 3]}, f)

    # Create plot
    plt.plot([1, 2, 3])
    plt.savefig('/workspace/plot.png')

    # Create text file
    with open('/workspace/readme.txt', 'w') as f:
        f.write("Generated files")
    `);

    // Download all files
    const filesToDownload = [
      ['/workspace/data.json', './downloaded_data.json'],
      ['/workspace/plot.png', './downloaded_plot.png'],
      ['/workspace/readme.txt', './downloaded_readme.txt']
    ];

    console.log('📥 Downloading files...');
    for (const [remotePath, localPath] of filesToDownload) {
      try {
        const content = await sandbox.files.download(remotePath);
        fs.writeFileSync(localPath, content);
        const stats = fs.statSync(localPath);
        const fileSize = stats.size / 1024;
        console.log(`  ✅ ${remotePath} → ${localPath} (${fileSize.toFixed(2)} KB)`);
      } catch (error) {
        console.error(`  ❌ Failed to download ${remotePath}: ${error.message}`);
      }
    }

    await sandbox.kill();
    ```
  </Tab>
</Tabs>

## Download All Files in Directory

Download all files from a directory:

<Tabs>
  <Tab title="Python">
    ```python theme={null}
    from hopx_ai import Sandbox
    import os

    sandbox = Sandbox.create(template="code-interpreter")

    # Create multiple files
    for i in range(3):
        sandbox.files.write(f'/workspace/file_{i}.txt', f'Content {i}')

    # Create local directory
    os.makedirs('./downloads', exist_ok=True)

    # Download all files
    files = sandbox.files.list('/workspace')
    print("📥 Downloading all files...")
    for file in files:
        if file.is_file:
            local_path = f'./downloads/{file.name}'
            try:
                sandbox.files.download(file.path, local_path)
                print(f"  ✅ {file.name} ({file.size_kb:.2f} KB)")
            except Exception as e:
                print(f"  ❌ Failed to download {file.name}: {e}")

    sandbox.kill()
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    import { Sandbox } from '@hopx-ai/sdk';
    import * as fs from 'fs';
    import * as path from 'path';

    const sandbox = await Sandbox.create({ template: 'code-interpreter' });

    // Create multiple files
    for (let i = 0; i < 3; i++) {
      await sandbox.files.write(`/workspace/file_${i}.txt`, `Content ${i}`);
    }

    // Create local directory
    if (!fs.existsSync('./downloads')) {
      fs.mkdirSync('./downloads');
    }

    // Download all files
    const files = await sandbox.files.list('/workspace');
    console.log('📥 Downloading all files...');
    for (const file of files) {
      if (file.isFile) {
        const localPath = `./downloads/${file.name}`;
        try {
          const content = await sandbox.files.download(file.path);
          fs.writeFileSync(localPath, content);
          console.log(`  ✅ ${file.name} (${(file.size / 1024).toFixed(2)} KB)`);
        } catch (error) {
          console.error(`  ❌ Failed to download ${file.name}: ${error.message}`);
        }
      }
    }

    await sandbox.kill();
    ```
  </Tab>
</Tabs>

## Error Handling

Handle download errors:

<Tabs>
  <Tab title="Python">
    ```python theme={null}
    from hopx_ai import Sandbox
    from hopx_ai.errors import FileNotFoundError, FileOperationError

    sandbox = Sandbox.create(template="code-interpreter")

    try:
        # Try to download non-existent file
        sandbox.files.download('/workspace/nonexistent.txt', './downloaded.txt')
    except FileNotFoundError:
        print("File not found in sandbox")
    except FileOperationError as e:
        print(f"Download failed: {e}")

    # Check if file exists first
    if sandbox.files.exists('/workspace/data.txt'):
        sandbox.files.download('/workspace/data.txt', './data.txt')
        print("Download successful")
    else:
        print("File does not exist")

    sandbox.kill()
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    import { Sandbox } from '@hopx-ai/sdk';
    import { FileNotFoundError, FileOperationError } from '@hopx-ai/sdk';

    const sandbox = await Sandbox.create({ template: 'code-interpreter' });

    try {
      // Try to download non-existent file
      await sandbox.files.download('/workspace/nonexistent.txt');
    } catch (error) {
      if (error instanceof FileNotFoundError) {
        console.error('File not found in sandbox');
      } else if (error instanceof FileOperationError) {
        console.error(`Download failed: ${error.message}`);
      }
    }

    // Check if file exists first
    const exists = await sandbox.files.exists('/workspace/data.txt');
    if (exists) {
      const content = await sandbox.files.download('/workspace/data.txt');
      fs.writeFileSync('./data.txt', content);
      console.log('Download successful');
    } else {
      console.log('File does not exist');
    }

    await sandbox.kill();
    ```
  </Tab>
</Tabs>

## Complete Example

Here's a complete download workflow:

<Tabs>
  <Tab title="Python">
    ```python theme={null}
    from hopx_ai import Sandbox
    import os

    sandbox = Sandbox.create(template="code-interpreter")

    # Generate outputs
    sandbox.run_code('''
    import json
    import matplotlib.pyplot as plt
    import pandas as pd

    # Generate JSON data
    data = {"results": [1, 2, 3, 4, 5]}
    with open('/workspace/results.json', 'w') as f:
        json.dump(data, f, indent=2)

    # Generate plot
    plt.figure(figsize=(10, 6))
    plt.plot([1, 2, 3, 4, 5], [1, 4, 9, 16, 25])
    plt.title("Results Visualization")
    plt.savefig('/workspace/results.png')

    # Generate CSV
    df = pd.DataFrame({"x": [1, 2, 3], "y": [4, 5, 6]})
    df.to_csv('/workspace/data.csv', index=False)
    ''')

    # Create local output directory
    os.makedirs('./outputs', exist_ok=True)

    # Download all generated files
    print("📥 Downloading generated outputs...")
    files = sandbox.files.list('/workspace')
    total_size = 0

    for file in files:
        if file.is_file and file.name in ['results.json', 'results.png', 'data.csv']:
            local_path = f'./outputs/{file.name}'
            try:
                sandbox.files.download(file.path, local_path, timeout=120)
                total_size += file.size
                print(f"  ✅ {file.name} ({file.size_kb:.2f} KB)")
            except Exception as e:
                print(f"  ❌ Failed to download {file.name}: {e}")

    print(f"\n✅ Total downloaded: {total_size / 1024:.2f} KB")
    print(f"📁 Files saved to: ./outputs/")

    sandbox.kill()
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    import { Sandbox } from '@hopx-ai/sdk';
    import * as fs from 'fs';

    const sandbox = await Sandbox.create({ template: 'code-interpreter' });

    // Generate outputs
    await sandbox.runCode(`
    import json
    import matplotlib.pyplot as plt
    import pandas as pd

    # Generate JSON data
    data = {"results": [1, 2, 3, 4, 5]}
    with open('/workspace/results.json', 'w') as f:
        json.dump(data, f, indent=2)

    # Generate plot
    plt.figure(figsize=(10, 6))
    plt.plot([1, 2, 3, 4, 5], [1, 4, 9, 16, 25])
    plt.title("Results Visualization")
    plt.savefig('/workspace/results.png')

    # Generate CSV
    df = pd.DataFrame({"x": [1, 2, 3], "y": [4, 5, 6]})
    df.to_csv('/workspace/data.csv', index=False)
    `);

    // Create local output directory
    if (!fs.existsSync('./outputs')) {
      fs.mkdirSync('./outputs');
    }

    // Download all generated files
    console.log('📥 Downloading generated outputs...');
    const files = await sandbox.files.list('/workspace');
    let totalSize = 0;

    for (const file of files) {
      if (file.isFile && ['results.json', 'results.png', 'data.csv'].includes(file.name)) {
        const localPath = `./outputs/${file.name}`;
        try {
          const content = await sandbox.files.download(file.path);
          fs.writeFileSync(localPath, content);
          totalSize += file.size;
          console.log(`  ✅ ${file.name} (${(file.size / 1024).toFixed(2)} KB)`);
        } catch (error) {
          console.error(`  ❌ Failed to download ${file.name}: ${error.message}`);
        }
      }
    }

    console.log(`\n✅ Total downloaded: ${(totalSize / 1024).toFixed(2)} KB`);
    console.log('📁 Files saved to: ./outputs/');

    await sandbox.kill();
    ```
  </Tab>
</Tabs>

## Best Practices

<Steps>
  <Step title="1. Check File Existence">
    Use `files.exists()` before downloading to avoid errors, or handle `FileNotFoundError` appropriately.
  </Step>

  <Step title="2. Set Timeouts for Large Files">
    For large files, set extended timeouts (60+ seconds) to avoid connection timeouts.
  </Step>

  <Step title="3. Create Local Directories">
    Create local directories before downloading to ensure files are saved correctly.
  </Step>

  <Step title="4. Handle Errors Gracefully">
    Wrap downloads in try/catch blocks to handle network errors, file not found, etc.
  </Step>

  <Step title="5. Verify Downloads">
    After downloading, verify files exist locally and check their sizes to ensure successful transfer.
  </Step>
</Steps>

## Related

* **[Reading Files](/core-concepts/filesystem/reading)** - Read file contents
* **[Uploading Files](/core-concepts/filesystem/uploading)** - Upload files to sandboxes
* **[Listing Files](/core-concepts/filesystem/listing)** - List directory contents
* **SDK**: [sandbox.files.download()](/sdk/python/files#download) - Python SDK method
* [CLI File Operations](/cli/commands/files) - File operations from CLI

## Next Steps

* Learn about [Uploading Files](/core-concepts/filesystem/uploading) to transfer files to sandboxes
* Explore [Reading Files](/core-concepts/filesystem/reading) to access file contents
* Review [Watching Files](/core-concepts/filesystem/watching) for real-time file monitoring
