escher-execution-engine 0.1.2

Production-ready async execution engine for system commands
Documentation
// Python Execution Example
//
// Demonstrates how to execute Python scripts using the execution engine.
// Run with: cargo run --example python_execution

use execution_engine::*;
use std::sync::Arc;
use std::collections::HashMap;

#[tokio::main]
async fn main() {
    println!("=== Python Script Execution Example ===\n");

    // Create engine with default config
    let config = ExecutionConfig::default();
    let engine = Arc::new(ExecutionEngine::new(config).unwrap());

    println!("✓ Execution engine created\n");

    // ========================================================================
    // Method 1: Using Command::Script (Recommended for script files)
    // ========================================================================
    println!("Method 1: Command::Script");
    println!("─────────────────────────");

    let request = ExecutionRequest {
        id: Uuid::new_v4(),
        command: Command::Script {
            path: PathBuf::from("test-scripts/demo.py"),
            interpreter: Some("python3".to_string()),
        },
        env: {
            let mut env = HashMap::new();
            env.insert("CUSTOM_VAR".to_string(), "Hello from Rust!".to_string());
            env
        },
        working_dir: None,
        timeout_ms: Some(10000), // 10 second timeout
        output_log_path: None,
        metadata: ExecutionMetadata::default(),
    };

    match engine.execute(request).await {
        Ok(execution_id) => {
            println!("  Execution ID: {}", execution_id);

            // Wait for completion
            match engine.wait_for_completion(execution_id).await {
                Ok(result) => {
                    println!("  Status: {:?}", result.status);
                    println!("  Success: {}", result.success);
                    println!("  Exit code: {}", result.exit_code);
                    println!("  Duration: {:?}", result.duration);
                    println!("\n  Stdout:");
                    println!("{}", result.stdout);

                    if !result.stderr.is_empty() {
                        println!("\n  Stderr:");
                        println!("{}", result.stderr);
                    }
                }
                Err(e) => println!("  Error waiting for result: {}", e),
            }
        }
        Err(e) => println!("  Failed to execute: {}", e),
    }

    println!("\n");

    // ========================================================================
    // Method 2: Using Command::Exec (Direct execution with arguments)
    // ========================================================================
    println!("Method 2: Command::Exec");
    println!("───────────────────────");

    let request = ExecutionRequest {
        id: Uuid::new_v4(),
        command: Command::Exec {
            program: "python3".to_string(),
            args: vec![
                "test-scripts/demo.py".to_string(),
                "--arg1".to_string(),
                "value1".to_string(),
            ],
        },
        env: HashMap::new(),
        working_dir: None,
        timeout_ms: Some(10000),
        output_log_path: None,
        metadata: ExecutionMetadata::default(),
    };

    match engine.execute(request).await {
        Ok(execution_id) => {
            println!("  Execution ID: {}", execution_id);

            // Wait for completion
            match engine.wait_for_completion(execution_id).await {
                Ok(result) => {
                    println!("  Status: {:?}", result.status);
                    println!("  Success: {}", result.success);
                    println!("\n  Stdout:");
                    println!("{}", result.stdout);
                }
                Err(e) => println!("  Error: {}", e),
            }
        }
        Err(e) => println!("  Failed to execute: {}", e),
    }

    println!("\n");

    // ========================================================================
    // Method 3: Using Command::Shell (Shell command string)
    // ========================================================================
    println!("Method 3: Command::Shell");
    println!("────────────────────────");

    let request = ExecutionRequest {
        id: Uuid::new_v4(),
        command: Command::Shell {
            command: "python3 test-scripts/demo.py".to_string(),
            shell: "/bin/bash".to_string(),
        },
        env: HashMap::new(),
        working_dir: None,
        timeout_ms: Some(10000),
        output_log_path: None,
        metadata: ExecutionMetadata::default(),
    };

    match engine.execute(request).await {
        Ok(execution_id) => {
            println!("  Execution ID: {}", execution_id);

            match engine.wait_for_completion(execution_id).await {
                Ok(result) => {
                    println!("  Status: {:?}", result.status);
                    println!("  Success: {}", result.success);
                    println!("\n  Stdout:");
                    println!("{}", result.stdout);
                }
                Err(e) => println!("  Error: {}", e),
            }
        }
        Err(e) => println!("  Failed to execute: {}", e),
    }

    println!("\n");

    // ========================================================================
    // Method 4: Simple inline Python code execution
    // ========================================================================
    println!("Method 4: Inline Python code");
    println!("────────────────────────────");

    let python_code = r#"
import sys
print("Hello from inline Python!")
print(f"Python version: {sys.version_info.major}.{sys.version_info.minor}")
for i in range(3):
    print(f"Count: {i}")
"#;

    let request = ExecutionRequest {
        id: Uuid::new_v4(),
        command: Command::Shell {
            command: format!("python3 -c '{}'", python_code.replace('\n', "; ")),
            shell: "/bin/bash".to_string(),
        },
        env: HashMap::new(),
        working_dir: None,
        timeout_ms: Some(5000),
        output_log_path: None,
        metadata: ExecutionMetadata::default(),
    };

    match engine.execute(request).await {
        Ok(execution_id) => {
            match engine.wait_for_completion(execution_id).await {
                Ok(result) => {
                    println!("  Success: {}", result.success);
                    println!("\n  Output:");
                    println!("{}", result.stdout);
                }
                Err(e) => println!("  Error: {}", e),
            }
        }
        Err(e) => println!("  Failed to execute: {}", e),
    }

    println!("\n=== All Python execution methods demonstrated ===");
}