Metadata-Version: 2.4
Name: dify-sandbox
Version: 1.1.1
Summary: Python SDK for JDify Sandbox API
Home-page: https://github.com/zjwan461/jdify-sandbox
Author: Jerry
Author-email: 826935261@qq.com
License: MIT
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Requires-Python: >=3.7
Description-Content-Type: text/markdown
Requires-Dist: requests>=2.25.0
Provides-Extra: dev
Requires-Dist: pytest>=6.0; extra == "dev"
Requires-Dist: pytest-cov>=2.0; extra == "dev"
Requires-Dist: black>=21.0; extra == "dev"
Requires-Dist: mypy>=0.900; extra == "dev"
Dynamic: author
Dynamic: author-email
Dynamic: classifier
Dynamic: description
Dynamic: description-content-type
Dynamic: home-page
Dynamic: license
Dynamic: provides-extra
Dynamic: requires-dist
Dynamic: requires-python
Dynamic: summary

# Dify Sandbox Python SDK

Python SDK for interacting with the Dify Sandbox API.

## Installation

```bash
pip install -e sdk/
```

Or install dependencies directly:

```bash
pip install requests
```

## Quick Start

```python
from dify_sandbox import DifySandboxClient

# Initialize client
client = DifySandboxClient(
    base_url="http://localhost:8194",
    api_key="your-api-key"
)

# Run Python code
result = client.run_python("print('Hello from sandbox!')")
print(result.stdout)  # Output: Hello from sandbox!

# Run Node.js code
result = client.run_nodejs("console.log('Hello from Node.js!')")
print(result.stdout)  # Output: Hello from Node.js!
## Features

- **Code Execution**: Run Python and Node.js code in a secure sandbox
- **File Operations**: Upload, download, and delete files to/from the sandbox
- **Dependency Management**: View and manage sandbox dependencies
- **Package Installation**: Install Python packages via pip with version specifier support
- **Command Execution**: Run commands in the sandbox upload directory with security restrictions
- **Health Check**: Monitor sandbox server status

## Recent Updates

### Command & Package Installation APIs (Latest)

Added two new endpoints for package installation and command execution:

```python
# Install a Python package (supports version specifiers)
result = client.install_package("requests==2.31.0", enable_network=True)
print(result.stdout)

# Run a command in the sandbox upload directory
result = client.run_command("python3", ["script.py"], enable_network=False)
print(result.stdout)
```

### File Deletion API

Added support for deleting files from the sandbox:

```python
# Delete a file from sandbox
response = client.delete_file("uploaded_file.txt")
print(response.message)  # Deletion result message
```

The default upload directory has also been updated for better file management.

## API Reference

### Client Initialization

```python
client = DifySandboxClient(
    base_url="http://localhost:8194",  # Sandbox server URL
    api_key="your-api-key",             # API key for authentication
    timeout=30                          # Request timeout in seconds
)
```

### Code Execution

#### Run Python Code

```python
result = client.run_python(
    code="print('Hello, World!')",
    preload="",              # Optional: code to run before main code
    enable_network=False     # Optional: enable network access
)

print(result.stdout)    # Standard output
print(result.stderr)    # Standard error
print(result.exit_code) # Exit code (0 = success)
```

#### Run Node.js Code

```python
result = client.run_nodejs(
    code="console.log('Hello, World!')",
    preload="",
    enable_network=False
)

print(result.stdout)
print(result.stderr)
print(result.exit_code)
```

### File Operations

#### Upload File

```python
# Upload from file path
result = client.upload_file("/path/to/file.txt")
print(result.filename)  # Uploaded filename in sandbox
print(result.size)      # File size in bytes

# Upload from file object
with open("local_file.txt", "rb") as f:
    result = client.upload_file(f, filename="custom_name.txt")
```

#### Download File

```python
# Download to memory
content = client.download_file("sandbox_file.txt")

# Download to local file
client.download_file("sandbox_file.txt", save_path="local_copy.txt")
```

### Dependency Management

#### Get Dependencies

```python
deps = client.get_dependencies(language="python3")
print(deps.dependencies)  # List of installed packages
```

#### Update Dependencies

```python
response = client.update_dependencies(language="python3")
print(response.message)
```

#### Refresh Dependencies

```python
response = client.refresh_dependencies(language="python3")
print(response.message)
```

### Package Installation

#### Install Python Package

Install a Python package using pip. Supports version specifiers (`==`, `>=`, `~=`, etc.) and extras (`[security]`).

```python
# Install latest version
result = client.install_package("requests")
print(result.stdout)

# Install specific version
result = client.install_package("requests==2.31.0", enable_network=True)
print(result.exit_code)  # 0 = success
```

**Parameters:**
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `package_name` | `str` | Yes | Package name with optional version specifier |
| `enable_network` | `bool` | No | Allow network access during install (default: `True`) |

**Security:** Package names are validated to prevent command injection. Dangerous characters (`;|&$\`(){}`) and path traversal (`..`) are blocked. Git URLs and local paths are not supported.

### Command Execution

#### Run Command

Run a command in the sandbox upload directory. The working directory is always set to `upload_dir` to prevent path traversal attacks.

```python
# Run a Python script in the upload directory
result = client.run_command("python3", ["script.py"])
print(result.stdout)

# Run with network access
result = client.run_command("curl", ["-s", "https://example.com"], enable_network=True)
```

**Parameters:**
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `command` | `str` | Yes | Command to execute |
| `args` | `list` | No | Command arguments (default: `[]`) |
| `enable_network` | `bool` | No | Allow network access (default: `False`) |

**Security:** Dangerous commands (`rm`, `shutdown`, `kill`, `chmod`, `sudo`, etc.), dangerous paths (`/etc`, `/bin`, `C:\Windows`, etc.), and path traversal attempts are blocked.

### Health Check

```python
if client.health_check():
    print("Sandbox is healthy")
else:
    print("Sandbox is not responding")
```

## Data Models

### RunCodeResponse

```python
@dataclass
class RunCodeResponse:
    stdout: str      # Standard output from code execution
    stderr: str      # Standard error from code execution
    exit_code: int   # Exit code (0 = success)
```

### UploadFileResponse

```python
@dataclass
class UploadFileResponse:
    filename: str  # Filename in sandbox
    size: int      # File size in bytes
```

### DependencyInfo

```python
@dataclass
class DependencyInfo:
    language: str       # Language (python3/nodejs)
    dependencies: list  # List of dependencies
```

### InstallPackageResponse

```python
@dataclass
class InstallPackageResponse:
    stdout: str    # Standard output from pip install
    stderr: str    # Standard error from pip install
    exit_code: int # Exit code (0 = success)
```

### RunCommandResponse

```python
@dataclass
class RunCommandResponse:
    stdout: str    # Standard output from command execution
    stderr: str    # Standard error from command execution
    exit_code: int # Exit code (0 = success)
```

### DifySandboxResponse

```python
@dataclass
class DifySandboxResponse:
    code: int       # Response code (0 = success)
    message: str    # Response message
    data: Any       # Response data
```

## Examples

See the `examples/` directory for complete usage examples:

- `basic_usage.py` - Basic code execution examples
- `file_operations.py` - File upload and download examples
- `dependency_management.py` - Dependency management examples

## Error Handling

The SDK raises exceptions for API errors:

```python
try:
    result = client.run_python("invalid code")
except Exception as e:
    print(f"Error: {e}")
```

## License

MIT License
