Practical Sandboxes & MicroVM Recipes
Copy-paste ready, production-grade recipes for executing untrusted user code, statistical data pipelines, dynamic chart rendering, and automated file analysis inside isolated FOTOhub Firecracker microVMs.
All recipes execute via POST /sandbox/exec-python or POST /sandbox/exec-bash and return structured JSON in under 200 milliseconds.
Sandbox API Reference
The sandbox environment provides a highly secure, ephemeral environment for executing untrusted code.
Endpoint
POST https://apis.fotohub.app/sandbox/exec-python
Request Schema
{
"code": "string (Required) - The python code to execute",
"inputs": "dict (Optional) - Key-value pairs injected into the environment as `input` dict",
"timeout": "int (Optional) - Max execution time in seconds. Max 10.",
"memory_limit_mb": "int (Optional) - Memory limit in MB. Default 512."
}Response Schema
{
"ok": "bool - Whether execution succeeded without exceptions or timeouts",
"output": "string - Captured stdout / __FOTOHUB_RESULT__ value",
"error": "string|null - Traceback if an error occurred",
"execution_ms": "int - Wall time of execution",
"memory_mb": "int - Peak memory usage"
}The __FOTOHUB_RESULT__ Sentinel Pattern
To cleanly extract data from a sandbox execution without relying on fragile stdout parsing, assign your final result dictionary to the special __FOTOHUB_RESULT__ variable. The sandbox runtime will automatically serialize this variable and return it in the output field.
# Inside sandbox:
__FOTOHUB_RESULT__ = {"status": "success", "data": [1, 2, 3]}Security Boundaries & Limitations
- No network access: All outbound and inbound network requests are dropped at the hypervisor level.
- No filesystem persistence: The sandbox uses a
tmpfsoverlay. Everything is wiped instantly on exit. - No environment leakage: Host environment variables are completely scrubbed.
- Pre-installed Packages:
numpy,pandas,scipy,PIL,sklearn,matplotlib,bs4,requests,httpx.
Pricing
Sandboxes are billed strictly per-execution from your USD wallet. NO credits, NO PLN. Cost: $0.00008 / execution.
Multi-Language Client Code
import requests
def run_sandbox(code, inputs=None):
res = requests.post(
"https://apis.fotohub.app/sandbox/exec-python",
headers={"Authorization": "Bearer fh_live_YOUR_API_KEY"},
json={"code": code, "inputs": inputs or {}}
)
return res.json()import fetch from "node-fetch";
const runSandbox = async (code: string, inputs = {}) => {
const res = await fetch("https://apis.fotohub.app/sandbox/exec-python", {
method: "POST",
headers: {
"Authorization": "Bearer fh_live_YOUR_API_KEY",
"Content-Type": "application/json"
},
body: JSON.stringify({ code, inputs })
});
return res.json();
};curl -X POST https://apis.fotohub.app/sandbox/exec-python \
-H "Authorization: Bearer fh_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"code": "print(1+1)"}'package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
func runSandbox(code string, inputs map[string]interface{}) {
url := "https://apis.fotohub.app/sandbox/exec-python"
payload := map[string]interface{}{"code": code, "inputs": inputs}
jsonValue, _ := json.Marshal(payload)
req, _ := http.NewRequest("POST", url, bytes.NewBuffer(jsonValue))
req.Header.Set("Authorization", "Bearer fh_live_YOUR_API_KEY")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
res, _ := client.Do(req)
defer res.Body.Close()
fmt.Println("Sandbox executed")
}15 New Recipes
1. Pandas DataFrame operations (filter, groupby, pivot)
code = '''
import pandas as pd
df = pd.DataFrame(inputs['data'])
filtered = df[df['sales'] > 100]
pivot = filtered.pivot_table(index='region', values='sales', aggfunc='sum')
__FOTOHUB_RESULT__ = pivot.to_dict()
'''2. Regular expression batch extraction from HTML/text
code = '''
import re
text = inputs['text']
emails = re.findall(r'[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}', text)
__FOTOHUB_RESULT__ = {"emails": emails}
'''3. JSON Schema validation with jsonschema library
code = '''
from jsonschema import validate
try:
validate(instance=inputs['data'], schema=inputs['schema'])
__FOTOHUB_RESULT__ = {"valid": True}
except Exception as e:
__FOTOHUB_RESULT__ = {"valid": False, "error": str(e)}
'''4. Base64 encode/decode binary data
code = '''
import base64
decoded = base64.b64decode(inputs['b64_str'])
__FOTOHUB_RESULT__ = {"bytes_len": len(decoded)}
'''5. Time series smoothing with SciPy
code = '''
from scipy.signal import savgol_filter
smoothed = savgol_filter(inputs['series'], window_length=5, polyorder=2)
__FOTOHUB_RESULT__ = {"smoothed": smoothed.tolist()}
'''6. PDF text extraction with pdfplumber
code = '''
import pdfplumber
import io
import base64
pdf_bytes = base64.b64decode(inputs['pdf_b64'])
with pdfplumber.open(io.BytesIO(pdf_bytes)) as pdf:
text = "\n".join([page.extract_text() for page in pdf.pages])
__FOTOHUB_RESULT__ = {"text": text}
'''7. Markdown to HTML conversion with markdown library
code = '''
import markdown
html = markdown.markdown(inputs['md_text'])
__FOTOHUB_RESULT__ = {"html": html}
'''8. Text similarity scoring with difflib.SequenceMatcher
code = '''
from difflib import SequenceMatcher
ratio = SequenceMatcher(None, inputs['text1'], inputs['text2']).ratio()
__FOTOHUB_RESULT__ = {"similarity": ratio}
'''9. Bulk URL validation and status checking with httpx
(Note: requires explicit network mock or pre-fetched data, as network is blocked)
code = '''
# Since network is blocked, we use this to parse and validate URL structures
from urllib.parse import urlparse
valid = [url for url in inputs['urls'] if urlparse(url).scheme in ('http', 'https')]
__FOTOHUB_RESULT__ = {"valid_urls": valid}
'''10. YAML to JSON conversion and validation
code = '''
import yaml
parsed = yaml.safe_load(inputs['yaml_str'])
__FOTOHUB_RESULT__ = {"json": parsed}
'''11. Cryptographic hash computation (SHA-256, MD5, BLAKE2)
code = '''
import hashlib
h = hashlib.sha256(inputs['text'].encode()).hexdigest()
__FOTOHUB_RESULT__ = {"sha256": h}
'''12. Number theory computations (primes, factorization)
code = '''
def is_prime(n):
if n < 2: return False
for i in range(2, int(n**0.5) + 1):
if n % i == 0: return False
return True
__FOTOHUB_RESULT__ = {"is_prime": is_prime(inputs['number'])}
'''13. Color palette extraction from image bytes
code = '''
from PIL import Image
import io, base64
img_bytes = base64.b64decode(inputs['image_b64'])
img = Image.open(io.BytesIO(img_bytes)).convert("P", palette=Image.ADAPTIVE, colors=5)
palette = img.getpalette()[:15]
__FOTOHUB_RESULT__ = {"palette": [palette[i:i+3] for i in range(0, 15, 3)]}
'''14. ASCII chart generation from numerical data
code = '''
def ascii_bar(val, max_val, width=20):
bars = int((val / max_val) * width)
return "█" * bars
chart = {k: ascii_bar(v, max(inputs['data'].values())) for k, v in inputs['data'].items()}
__FOTOHUB_RESULT__ = {"chart": chart}
'''15. Geospatial distance calculation (Haversine formula)
code = '''
import math
def haversine(lat1, lon1, lat2, lon2):
R = 6371
dlat, dlon = math.radians(lat2 - lat1), math.radians(lon2 - lon1)
a = math.sin(dlat/2)**2 + math.cos(math.radians(lat1)) * math.cos(math.radians(lat2)) * math.sin(dlon/2)**2
return R * (2 * math.atan2(math.sqrt(a), math.sqrt(1 - a)))
__FOTOHUB_RESULT__ = {"distance_km": haversine(*inputs['coords'])}
'''Advanced Patterns
Passing Large Data
Fetch from FOTOhub S3 inside the sandbox or chunk it.
# Pass S3 keys via inputs instead of raw data
code = '''
import requests
# Using VPC endpoints for S3 (s1.fotohub.app) - no egress cost!
data = requests.get(f"http://s1.fotohub.app/{inputs['bucket']}/{inputs['key']}").content
'''Parallel Sandbox Execution
Use asyncio to fan-out sandbox tasks.
import asyncio
import httpx
async def run_parallel(codes):
async with httpx.AsyncClient() as client:
tasks = [client.post("https://apis.fotohub.app/sandbox/exec-python", json={"code": c}) for c in codes]
return await asyncio.gather(*tasks)Chunking Large Datasets
If your dataframe exceeds sandbox memory, split it across multiple requests.
import pandas as pd
import math
import requests
def chunk_execution(df, chunk_size=10000):
num_chunks = math.ceil(len(df) / chunk_size)
results = []
for i in range(num_chunks):
chunk = df.iloc[i * chunk_size : (i + 1) * chunk_size]
# Send chunk to sandbox
res = requests.post(
"https://apis.fotohub.app/sandbox/exec-python",
headers={"Authorization": "Bearer fh_live_YOUR_API_KEY"},
json={
"code": '''
import pandas as pd
df = pd.DataFrame(inputs['data'])
# Complex data processing here
res = df.groupby('category').sum()
__FOTOHUB_RESULT__ = res.to_dict()
''',
"inputs": {"data": chunk.to_dict(orient="list")}
}
)
results.append(res.json()["output"])
# Merge results client-side
return resultsSandbox Result Caching Pattern
Repeatedly running the same operations on the same inputs can get expensive and slow. Implement a fast cache layer using Redis on your primary compute instance.
import hashlib
import json
import redis
import requests
r = redis.Redis(host='localhost', port=6379, db=0)
def cached_sandbox_exec(code, inputs):
# Create deterministic hash of inputs
payload = json.dumps({"code": code, "inputs": inputs}, sort_keys=True)
cache_key = f"sandbox_cache_{hashlib.md5(payload.encode()).hexdigest()}"
# Check cache
cached = r.get(cache_key)
if cached:
return json.loads(cached)
# Execute if not found
res = requests.post(
"https://apis.fotohub.app/sandbox/exec-python",
headers={"Authorization": "Bearer fh_live_YOUR_API_KEY"},
json={"code": code, "inputs": inputs}
)
# Save to cache with TTL
data = res.json()
if data.get("ok"):
r.setex(cache_key, 3600, json.dumps(data))
return dataOrchestrating Sandboxes with Apache Airflow
Integrate sandboxes as isolated task operators in your DAGs.
from airflow import DAG
from airflow.operators.python_operator import PythonOperator
from datetime import datetime
import requests
def run_ml_pipeline_step(**kwargs):
res = requests.post(
"https://apis.fotohub.app/sandbox/exec-python",
headers={"Authorization": "Bearer fh_live_YOUR_API_KEY"},
json={
"code": "import sklearn; ...; __FOTOHUB_RESULT__={'model_score': 0.94}"
}
)
return res.json()
dag = DAG('sandbox_ml_pipeline', start_date=datetime(2026, 1, 1))
task = PythonOperator(
task_id='train_model_sandboxed',
python_callable=run_ml_pipeline_step,
dag=dag
)Sandbox Result Caching Pattern
Repeatedly running the same operations on the same inputs can get expensive and slow. Implement a fast cache layer using Redis on your primary compute instance.
import hashlib
import json
import redis
import requests
r = redis.Redis(host='localhost', port=6379, db=0)
def cached_sandbox_exec(code, inputs):
# Create deterministic hash of inputs
payload = json.dumps({"code": code, "inputs": inputs}, sort_keys=True)
cache_key = f"sandbox_cache_{hashlib.md5(payload.encode()).hexdigest()}"
# Check cache
cached = r.get(cache_key)
if cached:
return json.loads(cached)
# Execute if not found
res = requests.post(
"https://apis.fotohub.app/sandbox/exec-python",
headers={"Authorization": "Bearer fh_live_YOUR_API_KEY"},
json={"code": code, "inputs": inputs}
)
# Save to cache with TTL
data = res.json()
if data.get("ok"):
r.setex(cache_key, 3600, json.dumps(data))
return dataOrchestrating Sandboxes with Apache Airflow
Integrate sandboxes as isolated task operators in your DAGs.
from airflow import DAG
from airflow.operators.python_operator import PythonOperator
from datetime import datetime
import requests
def run_ml_pipeline_step(**kwargs):
res = requests.post(
"https://apis.fotohub.app/sandbox/exec-python",
headers={"Authorization": "Bearer fh_live_YOUR_API_KEY"},
json={
"code": "import sklearn; ...; __FOTOHUB_RESULT__={'model_score': 0.94}"
}
)
return res.json()
dag = DAG('sandbox_ml_pipeline', start_date=datetime(2026, 1, 1))
task = PythonOperator(
task_id='train_model_sandboxed',
python_callable=run_ml_pipeline_step,
dag=dag
)Sandbox Result Caching Pattern
Repeatedly running the same operations on the same inputs can get expensive and slow. Implement a fast cache layer using Redis on your primary compute instance.
import hashlib
import json
import redis
import requests
r = redis.Redis(host='localhost', port=6379, db=0)
def cached_sandbox_exec(code, inputs):
# Create deterministic hash of inputs
payload = json.dumps({"code": code, "inputs": inputs}, sort_keys=True)
cache_key = f"sandbox_cache_{hashlib.md5(payload.encode()).hexdigest()}"
# Check cache
cached = r.get(cache_key)
if cached:
return json.loads(cached)
# Execute if not found
res = requests.post(
"https://apis.fotohub.app/sandbox/exec-python",
headers={"Authorization": "Bearer fh_live_YOUR_API_KEY"},
json={"code": code, "inputs": inputs}
)
# Save to cache with TTL
data = res.json()
if data.get("ok"):
r.setex(cache_key, 3600, json.dumps(data))
return dataOrchestrating Sandboxes with Apache Airflow
Integrate sandboxes as isolated task operators in your DAGs.
from airflow import DAG
from airflow.operators.python_operator import PythonOperator
from datetime import datetime
import requests
def run_ml_pipeline_step(**kwargs):
res = requests.post(
"https://apis.fotohub.app/sandbox/exec-python",
headers={"Authorization": "Bearer fh_live_YOUR_API_KEY"},
json={
"code": "import sklearn; ...; __FOTOHUB_RESULT__={'model_score': 0.94}"
}
)
return res.json()
dag = DAG('sandbox_ml_pipeline', start_date=datetime(2026, 1, 1))
task = PythonOperator(
task_id='train_model_sandboxed',
python_callable=run_ml_pipeline_step,
dag=dag
)Sandbox Result Caching Pattern
Repeatedly running the same operations on the same inputs can get expensive and slow. Implement a fast cache layer using Redis on your primary compute instance.
import hashlib
import json
import redis
import requests
r = redis.Redis(host='localhost', port=6379, db=0)
def cached_sandbox_exec(code, inputs):
# Create deterministic hash of inputs
payload = json.dumps({"code": code, "inputs": inputs}, sort_keys=True)
cache_key = f"sandbox_cache_{hashlib.md5(payload.encode()).hexdigest()}"
# Check cache
cached = r.get(cache_key)
if cached:
return json.loads(cached)
# Execute if not found
res = requests.post(
"https://apis.fotohub.app/sandbox/exec-python",
headers={"Authorization": "Bearer fh_live_YOUR_API_KEY"},
json={"code": code, "inputs": inputs}
)
# Save to cache with TTL
data = res.json()
if data.get("ok"):
r.setex(cache_key, 3600, json.dumps(data))
return dataOrchestrating Sandboxes with Apache Airflow
Integrate sandboxes as isolated task operators in your DAGs.
from airflow import DAG
from airflow.operators.python_operator import PythonOperator
from datetime import datetime
import requests
def run_ml_pipeline_step(**kwargs):
res = requests.post(
"https://apis.fotohub.app/sandbox/exec-python",
headers={"Authorization": "Bearer fh_live_YOUR_API_KEY"},
json={
"code": "import sklearn; ...; __FOTOHUB_RESULT__={'model_score': 0.94}"
}
)
return res.json()
dag = DAG('sandbox_ml_pipeline', start_date=datetime(2026, 1, 1))
task = PythonOperator(
task_id='train_model_sandboxed',
python_callable=run_ml_pipeline_step,
dag=dag
)Sandbox Result Caching Pattern
Repeatedly running the same operations on the same inputs can get expensive and slow. Implement a fast cache layer using Redis on your primary compute instance.
import hashlib
import json
import redis
import requests
r = redis.Redis(host='localhost', port=6379, db=0)
def cached_sandbox_exec(code, inputs):
# Create deterministic hash of inputs
payload = json.dumps({"code": code, "inputs": inputs}, sort_keys=True)
cache_key = f"sandbox_cache_{hashlib.md5(payload.encode()).hexdigest()}"
# Check cache
cached = r.get(cache_key)
if cached:
return json.loads(cached)
# Execute if not found
res = requests.post(
"https://apis.fotohub.app/sandbox/exec-python",
headers={"Authorization": "Bearer fh_live_YOUR_API_KEY"},
json={"code": code, "inputs": inputs}
)
# Save to cache with TTL
data = res.json()
if data.get("ok"):
r.setex(cache_key, 3600, json.dumps(data))
return dataOrchestrating Sandboxes with Apache Airflow
Integrate sandboxes as isolated task operators in your DAGs.
from airflow import DAG
from airflow.operators.python_operator import PythonOperator
from datetime import datetime
import requests
def run_ml_pipeline_step(**kwargs):
res = requests.post(
"https://apis.fotohub.app/sandbox/exec-python",
headers={"Authorization": "Bearer fh_live_YOUR_API_KEY"},
json={
"code": "import sklearn; ...; __FOTOHUB_RESULT__={'model_score': 0.94}"
}
)
return res.json()
dag = DAG('sandbox_ml_pipeline', start_date=datetime(2026, 1, 1))
task = PythonOperator(
task_id='train_model_sandboxed',
python_callable=run_ml_pipeline_step,
dag=dag
)Sandbox Result Caching Pattern
Repeatedly running the same operations on the same inputs can get expensive and slow. Implement a fast cache layer using Redis on your primary compute instance.
import hashlib
import json
import redis
import requests
r = redis.Redis(host='localhost', port=6379, db=0)
def cached_sandbox_exec(code, inputs):
# Create deterministic hash of inputs
payload = json.dumps({"code": code, "inputs": inputs}, sort_keys=True)
cache_key = f"sandbox_cache_{hashlib.md5(payload.encode()).hexdigest()}"
# Check cache
cached = r.get(cache_key)
if cached:
return json.loads(cached)
# Execute if not found
res = requests.post(
"https://apis.fotohub.app/sandbox/exec-python",
headers={"Authorization": "Bearer fh_live_YOUR_API_KEY"},
json={"code": code, "inputs": inputs}
)
# Save to cache with TTL
data = res.json()
if data.get("ok"):
r.setex(cache_key, 3600, json.dumps(data))
return dataOrchestrating Sandboxes with Apache Airflow
Integrate sandboxes as isolated task operators in your DAGs.
from airflow import DAG
from airflow.operators.python_operator import PythonOperator
from datetime import datetime
import requests
def run_ml_pipeline_step(**kwargs):
res = requests.post(
"https://apis.fotohub.app/sandbox/exec-python",
headers={"Authorization": "Bearer fh_live_YOUR_API_KEY"},
json={
"code": "import sklearn; ...; __FOTOHUB_RESULT__={'model_score': 0.94}"
}
)
return res.json()
dag = DAG('sandbox_ml_pipeline', start_date=datetime(2026, 1, 1))
task = PythonOperator(
task_id='train_model_sandboxed',
python_callable=run_ml_pipeline_step,
dag=dag
)
