Metadata-Version: 2.4
Name: codibox
Version: 1.0.1
Summary: A reusable package for executing Python code in Docker containers and extracting charts/images
Home-page: https://github.com/otmane-elbourki/codibox
Author: Otmane El Bourki
Author-email: otmane.elbourki@gmail.com
Project-URL: Bug Reports, https://github.com/otmane-elbourki/codibox/issues
Project-URL: Source, https://github.com/otmane-elbourki/codibox
Project-URL: Documentation, https://github.com/otmane-elbourki/codibox#readme
Keywords: docker,code-execution,sandbox,jupyter,notebook,matplotlib,charts,images,python-execution
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Software Development :: Build Tools
Classifier: Topic :: System :: Systems Administration
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Operating System :: OS Independent
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: dev
Requires-Dist: pytest>=7.0.0; extra == "dev"
Requires-Dist: black>=23.0.0; extra == "dev"
Requires-Dist: mypy>=1.0.0; extra == "dev"
Dynamic: author
Dynamic: author-email
Dynamic: classifier
Dynamic: description
Dynamic: description-content-type
Dynamic: home-page
Dynamic: keywords
Dynamic: license-file
Dynamic: project-url
Dynamic: provides-extra
Dynamic: requires-python
Dynamic: summary

# Codibox - Safe Code Execution Package

A reusable Python package for executing code in Docker containers and extracting charts/images.

## 🎯 Purpose

This package extracts the core functionality of executing Python code in Docker and extracting results. It's designed to be:

- **Reusable** across different projects
- **Configurable** for different use cases
- **Standalone** - works independently
- **Well-tested** and documented

## 📦 Installation

```bash
# Install as package
pip install -e ./codibox

# Or use directly
import sys
sys.path.insert(0, './codibox')
from codibox import DockerCodeExecutor
```

## 🚀 Quick Start

### Basic Usage

```python
from codibox import DockerCodeExecutor

# Initialize executor
executor = DockerCodeExecutor(container_name="sandbox")

# Execute code
result = executor.execute(
    code="""
    import matplotlib.pyplot as plt
    import pandas as pd
    
    # Create sample data
    data = [1, 2, 3, 4, 5]
    
    # Create chart
    plt.figure(figsize=(10, 6))
    plt.plot(data)
    plt.title('Sample Chart')
    plt.savefig('temp_code_files/chart.png')
    plt.show()
    """
)

# Check results
if result.success:
    print("✅ Execution successful!")
    print(f"📊 Found {len(result.images)} images")
    print(f"📄 Markdown length: {len(result.markdown)} characters")
    
    # Access images
    for img_path in result.images:
        print(f"  - {img_path}")
else:
    print(f"❌ Execution failed: {result.stderr}")
```

### With Input Files

```python
executor = DockerCodeExecutor(container_name="sandbox")

result = executor.execute(
    code="""
    import pandas as pd
    import matplotlib.pyplot as plt
    
    df = pd.read_csv('data.csv')
    plt.hist(df['age'], bins=20)
    plt.savefig('temp_code_files/age_distribution.png')
    plt.show()
    """,
    input_files=["datasets/customer_data.csv"]
)
```

### Process Images

```python
from codibox import ImageProcessor

# Execute code
result = executor.execute(code="...")

# Process images
processor = ImageProcessor()
markdown_with_images = processor.process_markdown(result.markdown)

# Or get all images as HTML
images_html = processor.get_all_images_html()
```

## 📋 API Reference

### `DockerCodeExecutor`

#### `__init__(container_name, host_temp_dir, image_output_dir, timeout, cleanup_on_error, auto_setup)`

Initialize the executor.

**Parameters:**
- `container_name` (str): Docker container name (default: "sandbox")
- `host_temp_dir` (str): Host temp directory (default: "/tmp")
- `image_output_dir` (str): Image directory in container (default: "temp_code_files")
- `timeout` (int, optional): Execution timeout in seconds (default: 300)
- `cleanup_on_error` (bool): Cleanup on error (default: True)
- `auto_setup` (bool): Automatically set up container if not running (default: False)

#### `execute(code, input_files, working_dir) -> ExecutionResult`

Execute Python code in Docker.

**Parameters:**
- `code` (str): Python code to execute
- `input_files` (List[str], optional): Input files to copy to container
- `working_dir` (str, optional): Working directory in container

**Returns:**
- `ExecutionResult` with:
  - `markdown`: Execution markdown output
  - `success`: Whether execution succeeded
  - `images`: List of image file paths
  - `csv_files`: List of generated CSV files
  - `stdout`: Standard output
  - `stderr`: Standard error
  - `execution_time`: Execution time in seconds

#### `check_container() -> bool`

Check if Docker container is running.

#### `get_container_status() -> Dict[str, Any]`

Get detailed status of the Docker container.

**Returns:**
- Dictionary with: `exists`, `running`, `status`, `image`

#### `setup_container(image_name, force_rebuild) -> bool`

Set up the Docker container by building the image and starting the container.

**Parameters:**
- `image_name` (str): Docker image name (default: "python_sandbox:latest")
- `force_rebuild` (bool): Rebuild image even if it exists (default: False)

**Returns:**
- `True` if setup successful, `False` otherwise

#### `start_container() -> bool`

Start an existing Docker container.

**Returns:**
- `True` if started successfully, `False` otherwise

#### `stop_container() -> bool`

Stop the Docker container.

**Returns:**
- `True` if stopped successfully, `False` otherwise

#### `ensure_container_running() -> bool`

Ensure the container is running. If not, try to start it or set it up.

**Returns:**
- `True` if container is running, `False` otherwise

### `ImageProcessor`

#### `__init__(image_base_dir)`

Initialize image processor.

#### `find_images() -> List[str]`

Find all image files in base directory.

#### `process_markdown(markdown) -> str`

Replace markdown image references with HTML.

#### `get_image_html(image_path) -> str`

Get HTML for a specific image.

## 🔧 Configuration

### Custom Container

```python
executor = DockerCodeExecutor(
    container_name="my_custom_container",
    host_temp_dir="/custom/tmp",
    image_output_dir="charts"
)
```

### Timeout Settings

```python
executor = DockerCodeExecutor(
    container_name="sandbox",
    timeout=600  # 10 minutes
)
```

## 📊 Use Cases

### 1. Chart Generation Service

```python
class ChartService:
    def __init__(self):
        self.executor = DockerCodeExecutor()
    
    def generate_chart(self, code: str, data_file: str = None):
        files = [data_file] if data_file else []
        result = self.executor.execute(code, input_files=files)
        return result
```

### 2. Code Testing Framework

```python
def test_code(code: str, expected_images: int = 1):
    executor = DockerCodeExecutor()
    result = executor.execute(code)
    assert result.success, f"Code failed: {result.stderr}"
    assert len(result.images) >= expected_images
    return result
```

### 3. Batch Processing

```python
def process_multiple_codes(codes: List[str]):
    executor = DockerCodeExecutor()
    results = []
    for code in codes:
        result = executor.execute(code)
        results.append(result)
    return results
```

## ✅ Advantages of This Approach

1. **Isolation**: Code runs in isolated Docker container
2. **Security**: No network access, limited resources
3. **Reproducibility**: Same environment every time
4. **Image Extraction**: Automatic chart discovery
5. **Error Handling**: Graceful fallbacks
6. **Reusability**: Works across different projects

## 🎯 Is This Approach Good?

### ✅ **Pros:**

1. **Security**: Isolated execution prevents malicious code
2. **Consistency**: Same environment for all executions
3. **Image Capture**: Notebook execution captures matplotlib outputs
4. **Flexibility**: Can handle any Python code
5. **Error Recovery**: Can fallback to direct Python execution

### ⚠️ **Considerations:**

1. **Performance**: Docker overhead (1-2 seconds per execution)
2. **Resource Usage**: Container needs to stay running
3. **Dependencies**: Requires Docker and container setup
4. **Network Isolation**: Code can't make API calls (by design)

### 💡 **Improvements Possible:**

1. **Caching**: Cache execution results for identical code
2. **Parallel Execution**: Run multiple codes in parallel
3. **Resource Limits**: Better memory/CPU limits
4. **Streaming**: Stream output as it executes
5. **Metrics**: Track execution times and success rates

## 🔄 Migration Guide

### From Current Code

**Before:**
```python
from agent_coder.agents import CodeExecutor

executor = CodeExecutor()
result, success, csv_files = executor._execute_code(code, filename)
```

**After:**
```python
from codibox import DockerCodeExecutor

executor = DockerCodeExecutor()
result = executor.execute(code, input_files=[filename])
# result.markdown, result.success, result.csv_files
```

## 📝 Examples

See `examples/` directory for complete usage examples:

- **`basic_usage.py`** - Simple code execution examples
- **`ai_analyst/streamlit_chart_generator.py`** - Complete Streamlit dashboard application
- **`README.md`** - Detailed examples documentation
- **`setup_example.sh`** - Quick setup script for examples

### Quick Start with Examples

```bash
# Setup Docker container
cd examples
./setup_example.sh

# Run basic examples
python basic_usage.py

# Run Streamlit app
cd examples/ai_analyst
streamlit run streamlit_chart_generator.py
```

See `examples/README.md` for full documentation.
