Safely managing files when working with AI-generated code is a critical challenge for modern development workflows. Building on our previous exploration of secure AI code execution in Part 1, we'll now focus on file management within sandbox environments.

We've already seen how LangChain and Daytona work together to generate and execute code safely - now it's time to dive deeper into controlling the files these systems create and modify. By leveraging Daytona's filesystem API, developers can create, modify, and execute files without compromising system security, while maintaining full control over their development environment.

Introduction to Daytona's Filesystem API

Managing files is crucial when working with AI-generated code in sandbox environments. Daytona's filesystem API provides programmatic access to workspace files, allowing you to create, modify, and manage files within the secure sandbox. Let's explore some practical examples of how to use these capabilities.

Basic File Operations

Example 1: Creating and Reading Files

Here's a simple example of creating a file and reading its contents:

from daytona_sdk import Daytona

def basic_file_operations():
    # Initialize Daytona
    daytona = Daytona()
    workspace = daytona.create()
    
    try:
        # Get workspace root directory
        root_dir = workspace.get_workspace_root_dir()
        
        # Create a new file
        file_path = f"{root_dir}/hello.txt"
        content = b"Hello from Daytona!"
        workspace.fs.upload_file(file_path, content)
        
        # Read the file contents
        file_content = workspace.fs.download_file(file_path)
        print(f"File contents: {file_content.decode('utf-8')}")
        
    finally:
        # Clean up
        daytona.remove(workspace)

Example 2: Working with Project Files

This example demonstrates how to manage multiple files in a project structure:

import os
from daytona_sdk import Daytona

def manage_project_files():
    daytona = Daytona()
    workspace = daytona.create()
    
    try:
        root_dir = workspace.get_workspace_root_dir()
        
        # Create project structure
        project_dir = os.path.join(root_dir, "my_project")
        workspace.fs.create_folder(project_dir, "755")
        
        # Create multiple files
        files = {
            "main.py": b"print('Hello, World!')",
            "config.json": b'{"setting": "value"}',
            "README.md": b"# My Project\nThis is a test project."
        }
        
        for filename, content in files.items():
            file_path = os.path.join(project_dir, filename)
            workspace.fs.upload_file(file_path, content)
        
        # List all files in the project
        project_files = workspace.fs.list_files(project_dir)
        print("Project files:", project_files)
        
    finally:
        daytona.remove(workspace)

Example 3: File Search and Replace

Here's how to search for specific content and replace it across files:

def search_and_replace():
    daytona = Daytona()
    workspace = daytona.create()
    
    try:
        root_dir = workspace.get_workspace_root_dir()
        
        # Create test files
        files = {
            "file1.txt": b"This is a test file with placeholder.",
            "file2.txt": b"Another file with placeholder text.",
            "file3.txt": b"No matching content here."
        }
        
        for filename, content in files.items():
            file_path = os.path.join(root_dir, filename)
            workspace.fs.upload_file(file_path, content)
        
        # Search for files containing "placeholder"
        matches = workspace.fs.find_files(root_dir, "placeholder")
        print(f"Found {len(matches)} files containing 'placeholder'")
        
        # Replace content in matching files
        for file_path in matches:
            workspace.fs.replace_in_files(
                [file_path],
                "placeholder",
                "updated content"
            )
            
        # Verify changes
        for file_path in matches:
            content = workspace.fs.download_file(file_path)
            print(f"Updated content in {file_path}:")
            print(content.decode('utf-8'))
            
    finally:
        daytona.remove(workspace)

Example 4: Managing File Permissions

Here's how to work with file permissions in your workspace:

def manage_file_permissions():
    daytona = Daytona()
    workspace = daytona.create()
    
    root_dir = workspace.get_workspace_root_dir()
    
    # Create a directory with specific permissions
    scripts_dir = os.path.join(root_dir, "scripts")
    workspace.fs.create_folder(scripts_dir, "755")  # rwxr-xr-x
    
    # Create an executable script
    script_path = os.path.join(scripts_dir, "run.sh")
    script_content = b"#!/bin/bash\necho 'Hello from script!'"
    workspace.fs.upload_file(script_path, script_content)
    
    # Make the script executable
    workspace.fs.set_file_permissions(script_path, "755")  # rwxr-xr-x
    
    # Create a config file with restricted permissions
    config_path = os.path.join(scripts_dir, "config.json")
    config_content = b'{"api_key": "secret123"}'
    workspace.fs.upload_file(config_path, config_content)
    workspace.fs.set_file_permissions(config_path, "600")  # rw-------
    
    # Get and display file permissions
    script_info = workspace.fs.get_file_details(script_path)
    config_info = workspace.fs.get_file_details(config_path)
    
    print(f"Script permissions: {script_info['mode']}")
    print(f"Config permissions: {config_info['mode']}")
    
    daytona.remove(workspace)

Best Practices for File Management

When working with Daytona's filesystem API, keep these best practices in mind:

  1. Handle file paths carefully using os.path.join() for cross-platform compatibility

  2. Set appropriate file permissions when creating directories and files

  3. Use binary mode (bytes) when uploading files to avoid encoding issues

  4. Implement error handling for file operations

Conclusion

Daytona's filesystem API provides powerful tools for managing files within sandbox environments. Combined with the secure execution capabilities we explored in Part 1, you can build sophisticated systems for working with AI-generated code while maintaining full control over the file system.

Our examples demonstrate common use cases, from basic file operations to more complex scenarios like managing permissions and handling large files. By following the best practices and leveraging these capabilities, you can build robust systems that safely manage files within AI sandbox environments.

What's Next?

In the next part of this series, we'll dive into Daytona's integration with Git and code analysis tools, exploring how to manage source control operations and leverage various code analysis capabilities to enhance your development workflow.