Full feature parity release - all 42 SDKs now implement: - Complete API coverage (58+ functions matching un.h spec) - HTTP 428 sudo OTP challenge handling - Comprehensive unit, integration, and functional tests |
||
|---|---|---|
| .. | ||
| awk | ||
| bash | ||
| c | ||
| clojure | ||
| cobol | ||
| cpp | ||
| crystal | ||
| csharp | ||
| d | ||
| dart | ||
| dotnet | ||
| elixir | ||
| erlang | ||
| forth | ||
| fortran | ||
| fsharp | ||
| go | ||
| groovy | ||
| haskell | ||
| java | ||
| javascript | ||
| julia | ||
| kotlin | ||
| lisp | ||
| lua | ||
| nim | ||
| objective-c | ||
| ocaml | ||
| perl | ||
| php | ||
| powershell | ||
| prolog | ||
| python | ||
| r | ||
| raku | ||
| ruby | ||
| rust | ||
| scala | ||
| scheme | ||
| swift | ||
| tcl | ||
| typescript | ||
| v | ||
| zig | ||
| CLI_SPEC.md | ||
| README.md | ||
Unsandbox SDK Clients
Multi-language SDK implementations for the Unsandbox API.
Each SDK is BOTH a library AND a CLI tool - see CLI_SPEC.md for the full CLI specification.
# Library usage
python -c "from un import execute_code; print(execute_code('python', 'print(1)'))"
# CLI usage (identical across all 42+ languages)
python un.py script.py
python un.py -s bash 'echo hello'
python un.py session --tmux
python un.py service --list
Directory Structure
clients/
├── python/
│ ├── sync/src/un.py # Synchronous (requests)
│ └── async/src/un_async.py # Asynchronous (aiohttp)
├── javascript/
│ ├── sync/src/un.js # Synchronous (https)
│ └── async/src/un_async.js # Asynchronous (fetch)
├── go/
│ ├── sync/src/un.go # Synchronous (net/http)
│ └── async/src/un_async.go # Asynchronous (goroutines)
├── java/
│ ├── sync/src/Un.java # Synchronous (HttpURLConnection)
│ └── async/src/UnsandboxAsync.java # Asynchronous (CompletableFuture)
├── ruby/
│ ├── sync/src/un.rb # Synchronous (net/http)
│ └── async/src/un_async.rb # Asynchronous (Future)
├── rust/
│ ├── sync/src/lib.rs # Synchronous (reqwest blocking)
│ └── async/src/lib.rs # Asynchronous (reqwest + tokio)
├── php/
│ ├── sync/src/un.php # Synchronous (cURL)
│ └── async/src/UnsandboxAsync.php # Asynchronous (Guzzle promises)
└── c/
└── src/unsandbox.c # Reference implementation
API Functions (43 total)
All SDKs implement the complete Unsandbox API:
Execute & Jobs (6 functions)
| Function | Description | Endpoint |
|---|---|---|
execute_code |
Execute code synchronously | POST /execute |
execute_async |
Execute code, return job ID | POST /execute (async mode) |
get_job |
Get job status | GET /jobs/{id} |
wait_for_job |
Poll until completion | GET /jobs/{id} (polling) |
cancel_job |
Cancel running job | DELETE /jobs/{id} |
list_jobs |
List all jobs | GET /jobs |
Sessions (9 functions)
| Function | Description | Endpoint |
|---|---|---|
list_sessions |
List all sessions | GET /sessions |
get_session |
Get session details | GET /sessions/{id} |
create_session |
Create interactive session | POST /sessions |
delete_session |
Terminate session | DELETE /sessions/{id} |
freeze_session |
Pause session | POST /sessions/{id}/freeze |
unfreeze_session |
Resume session | POST /sessions/{id}/unfreeze |
boost_session |
Add vCPUs | POST /sessions/{id}/boost |
unboost_session |
Remove boost | POST /sessions/{id}/unboost |
shell_session |
Execute shell command | POST /sessions/{id}/shell |
Services (16 functions)
| Function | Description | Endpoint |
|---|---|---|
list_services |
List all services | GET /services |
create_service |
Create persistent service | POST /services |
get_service |
Get service details | GET /services/{id} |
update_service |
Update/resize service | PATCH /services/{id} |
delete_service |
Destroy service | DELETE /services/{id} |
freeze_service |
Pause service | POST /services/{id}/freeze |
unfreeze_service |
Resume service | POST /services/{id}/unfreeze |
lock_service |
Prevent deletion | POST /services/{id}/lock |
unlock_service |
Allow deletion | POST /services/{id}/unlock |
get_service_logs |
Get bootstrap logs | GET /services/{id}/logs |
get_service_env |
Get env vault status | GET /services/{id}/env |
set_service_env |
Set environment vars | PUT /services/{id}/env |
delete_service_env |
Delete env vars | DELETE /services/{id}/env |
export_service_env |
Export decrypted env | POST /services/{id}/env/export |
redeploy_service |
Re-run bootstrap | POST /services/{id}/redeploy |
execute_in_service |
Run command in service | POST /services/{id}/execute |
Snapshots (8 functions)
| Function | Description | Endpoint |
|---|---|---|
list_snapshots |
List all snapshots | GET /snapshots |
get_snapshot |
Get snapshot details | GET /snapshots/{id} |
delete_snapshot |
Delete snapshot | DELETE /snapshots/{id} |
session_snapshot |
Snapshot a session | POST /sessions/{id}/snapshot |
service_snapshot |
Snapshot a service | POST /services/{id}/snapshot |
restore_snapshot |
Restore from snapshot | POST /snapshots/{id}/restore |
lock_snapshot |
Prevent deletion | POST /snapshots/{id}/lock |
unlock_snapshot |
Allow deletion | POST /snapshots/{id}/unlock |
clone_snapshot |
Clone snapshot | POST /snapshots/{id}/clone |
Utilities (4 functions)
| Function | Description | Endpoint |
|---|---|---|
get_languages |
Get supported languages | GET /languages (cached 1hr) |
detect_language |
Detect from filename | Local (no API call) |
validate_keys |
Validate API credentials | POST /keys/validate |
image |
Generate AI images | POST /image |
Authentication
4-Tier Credential Resolution
All SDKs resolve credentials in this priority order:
-
Function arguments (highest priority)
result = execute_code("python", code, public_key="pk-xxx", secret_key="sk-xxx") -
Environment variables
export UNSANDBOX_PUBLIC_KEY="unsb-pk-xxxx" export UNSANDBOX_SECRET_KEY="unsb-sk-xxxx" -
Home directory config
~/.unsandbox/accounts.csv Format: public_key,secret_key (one per line) -
Local directory config
./accounts.csv Format: public_key,secret_key (one per line)
HMAC-SHA256 Request Signing
Every API request includes:
Authorization: Bearer <public_key>
X-Timestamp: <unix_seconds>
X-Signature: HMAC-SHA256(secret_key, "timestamp:METHOD:path:body")
Example signature message:
1704067200:POST:/execute:{"language":"python","code":"print(1)"}
Caching
Languages Cache
All SDKs cache the /languages response:
- Location:
~/.unsandbox/languages.json - TTL: 1 hour (3600 seconds)
- Behavior: Check cache freshness before API call
Line Count Comparison
Why un.c is 6,354 lines vs Python's 1,714 lines
The reference C implementation includes infrastructure that high-level languages get from standard libraries:
| Component | un.c (lines) | Python | Notes |
|---|---|---|---|
| API Functions | ~2,500 | ~1,500 | Similar complexity |
| CLI main() | 1,306 | 0 | SDK is library-only |
| CLI help/usage | 154 | 0 | No CLI in SDK |
| HTTP client | 574 | 0 | requests library |
| JSON parsing | ~200 | 0 | json module |
| HMAC crypto | ~100 | 0 | hmac module |
| Memory management | ~300 | 0 | Garbage collected |
| String utilities | ~200 | 0 | Built-in |
| Total | 6,354 | 1,714 | 3.7x difference |
What Python Gets "For Free"
import requests # Replaces ~574 lines of curl code
import json # Replaces ~200 lines of JSON parsing
import hmac # Replaces ~100 lines of crypto
import hashlib # Replaces SHA-256 implementation
Feature Parity
Despite the line count difference, all SDKs implement:
- ✅ All 43 API functions
- ✅ 4-tier credential resolution
- ✅ HMAC-SHA256 request signing
- ✅ 1-hour languages caching
- ✅ Exponential backoff polling
- ✅ Proper error handling
The C implementation additionally includes:
- Full CLI with argument parsing
- Interactive shell support (WebSocket)
- Output formatting and display
- File input handling
SDK Size Summary
| Language | Sync | Async | Total | Notes |
|---|---|---|---|---|
| Python | 1,714 | 1,701 | 3,415 | requests/aiohttp |
| JavaScript | 1,131 | 1,209 | 2,340 | https/fetch |
| Go | 1,080 | 1,642 | 2,722 | net/http + goroutines |
| Java | 1,856 | 1,849 | 3,705 | HttpURLConnection |
| Ruby | 1,264 | 1,543 | 2,807 | net/http + Future |
| Rust | 1,856 | 1,949 | 3,805 | reqwest + tokio |
| PHP | 1,403 | 1,346 | 2,749 | cURL + Guzzle |
| Total | 21,543 |
Reference: un.c = 6,354 lines (includes CLI)
Usage Examples
Python (Sync)
from un import execute_code, list_services, image
# Execute code
result = execute_code("python", 'print("Hello, World!")')
print(result["stdout"])
# List services
services = list_services()
for svc in services:
print(f"{svc['name']}: {svc['status']}")
# Generate AI image
img = image("A sunset over mountains")
print(img["images"][0])
Python (Async)
import asyncio
from un_async import execute_code, list_services
async def main():
result = await execute_code("python", 'print("Hello!")')
print(result["stdout"])
asyncio.run(main())
JavaScript (Sync)
const un = require('./un');
const result = un.executeCode("javascript", 'console.log("Hello!")');
console.log(result.stdout);
Go
import "un"
func main() {
creds, _ := un.ResolveCredentials("", "")
result, _ := un.ExecuteCode(creds, "python", `print("Hello")`)
fmt.Println(result.Stdout)
}
Rust
use un::{execute_code, resolve_credentials};
fn main() -> Result<()> {
let creds = resolve_credentials(None, None)?;
let result = execute_code("python", r#"print("Hello")"#, &creds)?;
println!("{}", result.output);
Ok(())
}
Error Handling
All SDKs define these error types:
| Error | Description |
|---|---|
CredentialsError |
No credentials found or invalid |
APIError |
API returned error response |
TimeoutError |
Job polling exceeded timeout |
NetworkError |
Connection failed |
Contributing
When adding new API endpoints:
- Update all 14 SDK files (7 languages × 2 variants)
- Follow existing patterns for authentication and error handling
- Add proper documentation (docstrings/comments)
- Test with the SDK test framework
License
PUBLIC DOMAIN - No license, no warranty.
Part of the permacomputer project: https://permacomputer.com