Clouditia Manager SDK
Python SDK to manage remote GPU sessions on Clouditia via the Computing API (sk_compute_).
Installation
pip install clouditia-manager
This automatically installs the
clouditiaSDK (for code execution) andboto3(for S3 uploads).
1. Configuration
from clouditia_manager import GPUManager
# Default configuration (URL: https://clouditia.com/jobs)
manager = GPUManager(api_key="sk_compute_xxxxx")
# Advanced configuration
manager = GPUManager(
api_key="sk_compute_xxxxx",
base_url="https://clouditia.com/jobs", # API URL (default)
timeout=120 # Timeout in seconds (default: 60)
)
# Your API key is verified automatically
print(f"User: {manager.user['username']}")
print(f"Email: {manager.user['email']}")
Where to find your API key? Go to clouditia.com/manage/api-keys/ to create a
sk_compute_key.
2. Check available GPUs
Before launching a session, check GPU inventory in real-time:
inventory = manager.get_inventory()
if not inventory:
print("No GPUs available")
else:
for gpu in inventory:
print(f"{gpu.gpu_name} ({gpu.price_per_hour}EUR/h) : "
f"{gpu.available} available, {gpu.on_demand} on-demand || "
f"datacenter : {gpu.datacenter}, "
f"[datacenter_id : {gpu.datacenter_id}]")
Example output:
NVIDIA RTX 3090 (1.0EUR/h) : 1 available, 0 on-demand || datacenter : France-Poissy, [datacenter_id : e7aabe3c-...]
NVIDIA RTX 3060 Ti (0.5EUR/h) : 0 available, 4 on-demand || datacenter : France-vo8, [datacenter_id : 487754eb-...]
Status meanings:
- available: GPUs on powered-on machines, ready immediately
- on_demand: GPUs on powered-off machines, startup in ~2-5 minutes
- in_use: GPUs currently used by active sessions
Filter by datacenter
Use the datacenter_id (UUID) to filter inventory for a specific datacenter:
inventory = manager.get_inventory(datacenter_id="487754eb-a676-4502-a0f4-21a88e52c25a")
for gpu in inventory:
print(f"{gpu.gpu_name}: {gpu.available} available, {gpu.on_demand} on-demand")
List datacenters
datacenters = manager.list_datacenters()
for dc in datacenters:
print(f"{dc.name} (datacenter_id={dc.datacenter_id}) , GPUs: {dc.gpu_count}")
# Example output:
# France-Poissy (datacenter_id=e7aabe3c-...) , GPUs: 2
# France-vo8 (datacenter_id=487754eb-...) , GPUs: 4
3. Create a GPU session
Once you've chosen a GPU, launch a session. The SDK automatically waits until the session is ready:
session = manager.create_session(
gpu_type="nvidia-rtx-3090", # GPU type slug (from inventory)
vcpu=2, # Number of vCPUs
ram=4, # RAM in GB
storage=20 # Storage in GB
)
print(f"Session ready: {session.name}")
print(f"VS Code URL: {session.url}")
print(f"Password: {session.password}")
Target a specific datacenter
Use datacenter_id to launch the session on a specific datacenter:
session = manager.create_session(
gpu_type="nvidia-rtx-3060-ti",
vcpu=2, ram=4, storage=20,
datacenter_id="487754eb-a676-4502-a0f4-21a88e52c25a" # France-vo8
)
Progress tracking
The SDK monitors each creation step (power on, deployment, etc.) and displays progress in real-time. No need to set a timeout — the SDK detects real errors and returns them immediately:
session = manager.create_session(
gpu_type="nvidia-rtx-3090",
vcpu=4, ram=16, storage=20,
wait_ready=True, # Wait for session to be ready (default: True)
verbose=True # Show steps in real-time (default: True)
)
# Typical output (on-demand node):
# Waiting for session f091ef1c to be ready...
# [powering_on] Powering on node...
# [waiting_nodes] Waiting for nodes...
# [deploying] Deploying GPU session...
# [waiting_ready] Waiting for pod ready...
#
# SESSION READY
# ...
# Silent mode (no waiting, no output)
session = manager.create_session(
gpu_type="nvidia-rtx-3090",
vcpu=2, ram=4, storage=20,
wait_ready=False,
verbose=False
)
4. Stop a session
# Standard stop (waits for pod deletion)
result = manager.stop_session(f"{session.short_id}") # ex: "0e4c713a"
print(f"Session stopped: {result.name}")
# Silent mode
result = manager.stop_session(f"{session.short_id}", wait_stopped=False, verbose=False)
5. Execute code in a session
To execute code in an active session, generate a sk_live_ key and use the clouditia SDK.
Step 1: Generate an execution key
# Generate a sk_live_ key linked to the session
sdk_key = manager.generate_sdk_key(
session_id=session.short_id, # ex: "0e4c713a"
name="My Execution Key"
)
print(f"Key: {sdk_key}") # sk_live_xxxxx...
Step 2: Execute shell commands
from clouditia import GPUSession
session_live_gpu = GPUSession(api_key=sdk_key)
# Install system packages
result = session_live_gpu.shell("sudo apt update && sudo apt install -y ffmpeg")
print(result)
# Verify installation
result = session_live_gpu.shell("ffmpeg -version")
print(result)
# Install Python packages
result = session_live_gpu.shell("pip install transformers accelerate")
print(result)
# Verify installation
result = session_live_gpu.shell("python3 -c 'import transformers; print(transformers.__version__)'")
print(result)
# Execute a script from the workspace
result = session_live_gpu.shell("cd /home/coder/workspace && python3 train.py")
print(result)
Step 3: Execute Python code
# Execute Python code directly (via session_live_gpu.run)
result = session_live_gpu.run("""
import torch
print(f'CUDA: {torch.cuda.is_available()}')
print(f'GPU: {torch.cuda.get_device_name(0)}')
a = torch.randn(1000, 1000, device='cuda')
b = torch.randn(1000, 1000, device='cuda')
c = torch.matmul(a, b)
print(f'Result: {c.shape}')
""")
print(result)
Alternative: Lambda GPU (no session management)
For quick execution without creating a session manually, use lambda_gpu() (see section 10).
6. Manage sessions
List sessions
# All sessions
sessions = manager.list_sessions()
# Filter by status
running = manager.list_sessions(status="running")
stopped = manager.list_sessions(status="stopped")
for session in sessions:
print(f"{session.name} ({session.short_id}): {session.status} - {session.gpu_type}")
Get session details
session = manager.get_session("0e4c713a")
print(f"Name: {session.name}")
print(f"Status: {session.status}")
print(f"GPU: {session.gpu_type}")
print(f"URL: {session.url}")
print(f"Password: {session.password}")
Rename a session
session = manager.rename_session("0e4c713a", "my-ml-project-v1")
print(f"New name: {session.name}")
Session cost and duration
cost_info = manager.get_session_cost("0e4c713a")
print(f"Current cost: {cost_info['cost']} EUR")
print(f"Hourly rate: {cost_info['hourly_rate']} EUR/h")
print(f"Duration: {cost_info['duration_display']}")
Check credit balance
balance = manager.get_balance()
print(f"Balance: {balance['balance']} {balance['currency']}")
7. Multi-GPU sessions
Create a session with multiple GPUs, optionally of different types:
session = manager.create_session(
gpus=[
{'type': 'nvidia-rtx-3090', 'count': 1},
{'type': 'nvidia-rtx-3060-ti', 'count': 1}
],
vcpu=4,
ram=16,
storage=20
)
print(f"GPU Count: {session.gpu_count}")
print(f"GPUs: {session.gpus}")
GPU availability (allow_partial, auto_add_gpus)
If some requested GPUs are not available:
# Default: raises an error if any GPU is unavailable
session = manager.create_session(
gpus=[
{'type': 'nvidia-rtx-3090', 'count': 1},
{'type': 'nvidia-rtx-4090', 'count': 1} # If unavailable -> error
],
vcpu=4, ram=16, storage=20
)
# InsufficientResourcesError: Some GPUs unavailable: nvidia-rtx-4090.
# Use allow_partial=True to create with available GPUs only.
# allow_partial=True: create immediately with available GPUs only
session = manager.create_session(
gpus=[
{'type': 'nvidia-rtx-3090', 'count': 1},
{'type': 'nvidia-rtx-4090', 'count': 1}
],
vcpu=4, ram=16, storage=20,
allow_partial=True # Starts with 3090 only, no error
)
# auto_add_gpus=True: start with available GPUs, then automatically
# add missing GPUs when they become available (checks every 30s)
session = manager.create_session(
gpus=[
{'type': 'nvidia-rtx-3090', 'count': 1},
{'type': 'nvidia-rtx-4090', 'count': 1}
],
vcpu=4, ram=16, storage=20,
allow_partial=True,
auto_add_gpus=True # Background thread watches for nvidia-rtx-4090
)
8. Auto-stop limits
Set limits to automatically stop a session:
# Cost limit: auto-stop at 5 EUR
session = manager.create_session(
gpu_type="nvidia-rtx-3090",
vcpu=4, ram=16,
cost_limit=5.0
)
# Duration limit: auto-stop after 2 hours
session = manager.create_session(
gpu_type="nvidia-rtx-3090",
vcpu=4, ram=16,
duration_limit=7200 # seconds
)
# Both: stop when either limit is reached
session = manager.create_session(
gpu_type="nvidia-rtx-3090",
vcpu=4, ram=16,
cost_limit=10.0,
duration_limit=3600
)
print(f"Auto-stop enabled: {session.auto_stop_enabled}")
print(f"Cost limit: {session.cost_limit} EUR")
print(f"Duration limit: {session.duration_limit} seconds")
9. Queue
If GPUs are not immediately available, place your request in a queue:
result = manager.create_session(
gpu_type="nvidia-rtx-4090",
vcpu=4, ram=16, storage=20,
queue_if_unavailable=True
)
if hasattr(result, 'name'):
print(f"Session created: {result.name}")
elif isinstance(result, dict) and result.get('queued'):
print(f"Queued! Position: #{result['position']}")
print(f"Queue ID: {result['queue_id']}")
Manage the queue
# List queue jobs
queue_jobs = manager.list_queue_jobs()
for job in queue_jobs:
print(f"Position #{job.position}: {job.status_display}")
# Job details with history
result = manager.get_queue_job("a1b2c3d4", verbose=True)
# Cancel a job
manager.cancel_queue_job("a1b2c3d4")
10. Lambda GPU (Serverless Execution)
Execute Python code directly on a remote GPU, without managing a session:
result = manager.lambda_gpu(
script="""
import torch
print(f"CUDA: {torch.cuda.is_available()}")
if torch.cuda.is_available():
print(f"GPU: {torch.cuda.get_device_name(0)}")
a = torch.randn(5000, 5000, device='cuda')
b = torch.randn(5000, 5000, device='cuda')
c = torch.matmul(a, b)
print(f"5000x5000 matmul OK, shape: {c.shape}")
""",
gpu_type="nvidia-rtx-3060-ti",
vcpu=2,
ram=4,
storage=20
)
print(f"Exit code: {result.exit_code}")
print(f"Output: {result.stdout}")
print(f"Cost: {result.cost} EUR")
print(f"Duration: {result.duration_seconds}s")
Lambda with custom Docker environment
result = manager.lambda_gpu(
script="import torch; print(torch.cuda.is_available())",
gpu_type="nvidia-rtx-3090",
environment_id="3a07d1e9-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
vcpu=8, ram=32, storage=100
)
run_and_stop() (Full session with S3 upload)
Creates a session, uploads local files, executes a script on remote GPU, uploads results to S3, then stops the session automatically.
Step 1: Create local files
# Create train.py locally
with open("train.py", "w") as f:
f.write("""
import torch
import torch.nn as nn
import torch.optim as optim
import pandas as pd
import time
print("=" * 50)
print(" CLOUDITIA GPU TRAINING")
print("=" * 50)
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
print(f"Device: {device}")
if torch.cuda.is_available():
print(f"GPU: {torch.cuda.get_device_name(0)}")
# Load data
df = pd.read_csv('/home/coder/workspace/data.csv')
print(f"Data loaded: {len(df)} rows, {len(df.columns)} columns")
# Simple model
model = nn.Sequential(
nn.Linear(len(df.columns) - 1, 64),
nn.ReLU(),
nn.Linear(64, 32),
nn.ReLU(),
nn.Linear(32, 3)
).to(device)
optimizer = optim.Adam(model.parameters(), lr=0.001)
criterion = nn.CrossEntropyLoss()
print(f"Model parameters: {sum(p.numel() for p in model.parameters()):,}")
# Training loop
epochs = 10
for epoch in range(epochs):
x = torch.randn(64, len(df.columns) - 1).to(device)
y = torch.randint(0, 3, (64,)).to(device)
optimizer.zero_grad()
output = model(x)
loss = criterion(output, y)
loss.backward()
optimizer.step()
acc = (output.argmax(1) == y).float().mean().item()
print(f"Epoch {epoch+1}/{epochs} | Loss: {loss.item():.4f} | Acc: {acc:.2%}")
# Save model
torch.save(model.state_dict(), '/home/coder/workspace/model.pt')
print(f"Model saved to /home/coder/workspace/model.pt")
print("Training complete!")
""")
# Create a small data.csv locally
with open("data.csv", "w") as f:
f.write("sepal_length,sepal_width,petal_length,petal_width,species\\n")
f.write("5.1,3.5,1.4,0.2,0\\n")
f.write("4.9,3.0,1.4,0.2,0\\n")
f.write("7.0,3.2,4.7,1.4,1\\n")
f.write("6.4,3.2,4.5,1.5,1\\n")
f.write("6.3,3.3,6.0,2.5,2\\n")
f.write("5.8,2.7,5.1,1.9,2\\n")
Step 2: Run on remote GPU with S3 output
result = manager.run_and_stop(
script="python train.py",
gpu_type="nvidia-rtx-3090",
input_files=["train.py", "data.csv"], # local files uploaded to remote session
output_files=["model.pt"], # remote files uploaded to S3 after execution
s3_bucket="my-bucket",
s3_prefix="training-results/run-001/",
s3_access_key="YOUR_S3_ACCESS_KEY",
s3_secret_key="YOUR_S3_SECRET_KEY",
s3_endpoint="https://s3.amazonaws.com", # optional, default: AWS S3
s3_region="us-east-1" # optional, default: us-east-1
)
print(f"Success: {result.success}")
print(f"Exit code: {result.exit_code}")
print(f"Output: {result.stdout}")
print(f"Cost: {result.cost} EUR")
print(f"Duration: {result.duration_seconds}s")
11. Sessions resumed from custom environment
When you resume a session saved as a custom environment, the workspace must be re-downloaded from S3. The SDK handles this automatically:
session = manager.create_session(
gpu_type="nvidia-rtx-3090",
environment_id="3a07d1e9-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
vcpu=8, ram=32
)
# Displays a progress bar:
# Workspace restore [========............] 28.4% 3.12/10.98 GB ETA 124s
# Check progress manually
session = manager.get_session("0e4c713a")
print(f"Ready: {session.ready}")
if session.workspace_sync and session.workspace_sync.get("in_progress"):
print(f"Progress: {session.workspace_sync['pct']:.0f}%")
12. Notifications and costs
Send an email
# Send to yourself (default: your account email)
manager.send_email(
subject="Training Complete",
message="Accuracy: 95%, Model saved to S3"
)
# Send to a specific recipient
manager.send_email(
subject="Training Complete",
message="Accuracy: 95%",
to="colleague@company.com"
)
Generate an SDK key (sk_live_)
sdk_key = manager.generate_sdk_key("0e4c713a", name="My SDK key")
print(f"SDK key: {sdk_key}")
# Use with the clouditia SDK
from clouditia import GPUSession
session_live_gpu = GPUSession(api_key=sdk_key)
result = session_live_gpu.run("print('Hello!')")
Cost of multiple sessions
# Specific sessions
costs = manager.get_sessions_cost(["0e4c713a", "f0b09214"])
print(f"Total cost: {costs['total_cost']} EUR")
# All active sessions
active_costs = manager.get_active_sessions_cost()
print(f"Active sessions: {active_costs['session_count']}")
print(f"Total cost: {active_costs['total_cost']} EUR")
Error handling
from clouditia_manager import (
GPUManager,
AuthenticationError,
SessionNotFoundError,
InsufficientResourcesError,
APIError
)
try:
manager = GPUManager(api_key="sk_compute_xxxxx")
session = manager.create_session(gpu_type="nvidia-rtx-4090")
except AuthenticationError:
print("Invalid API key")
except InsufficientResourcesError:
print("No GPUs available")
except SessionNotFoundError:
print("Session not found")
except APIError as e:
print(f"API error: {e}")
API Reference
| Method | Description |
|---|---|
GPUManager(api_key, base_url, timeout) |
Initialize the SDK |
| Inventory | |
get_inventory(datacenter_id) |
Real-time GPU availability (available, on_demand, in_use) per datacenter |
list_datacenters() |
List available datacenters |
| Sessions | |
create_session(gpu_type, gpus, vcpu, ram, storage, datacenter_id, allow_partial, auto_add_gpus, ...) |
Create a GPU session |
stop_session(session_id, ...) |
Stop a session |
get_session(session_id) |
Session details |
list_sessions(status) |
List sessions |
rename_session(session_id, new_name) |
Rename a session |
generate_sdk_key(session_id, name) |
Generate a sk_live_ key for code execution |
| Lambda GPU | |
lambda_gpu(script, gpu_type, ...) |
Serverless execution on GPU |
run_and_stop(script, gpu_type, input_files, output_files, s3_bucket, ...) |
Full session with S3 upload |
| Queue | |
list_queue_jobs(status) |
List queue jobs |
get_queue_job(queue_id, verbose) |
Queue job details |
cancel_queue_job(queue_id) |
Cancel a queue job |
| Billing | |
get_balance() |
Credit balance |
get_session_cost(session_id) |
Session cost |
get_session_duration(session_id) |
Session duration |
get_sessions_cost(session_ids) |
Cost of multiple sessions |
get_active_sessions_cost() |
Cost of all active sessions |
| Other | |
send_email(subject, message, to=None) |
Send email notification (default: your email, or specify recipient) |
Object attributes
GPUSession
| Attribute | Type | Description |
|---|---|---|
id |
str | Full UUID |
short_id |
str | Short ID (8 characters) |
name |
str | Session name |
status |
str | running, stopped, pending, failed |
ready |
bool | True only if session is fully usable |
gpu_type |
str | GPU type(s) |
gpu_count |
int | Total number of GPUs |
gpus |
list | List of GPU configs (multi-GPU) |
vcpu |
int | Number of vCPUs |
ram |
str | Allocated RAM |
storage |
str | Allocated storage |
url |
str | VS Code access URL |
password |
str | VS Code password |
cost_limit |
float | Cost limit (EUR) |
duration_limit |
int | Duration limit (seconds) |
auto_stop_enabled |
bool | Auto-stop enabled |
estimated_ready_in_seconds |
int | ETA before ready |
workspace_sync |
dict | Workspace restore progress |
creation_step |
str | Current creation step |
creation_error |
str | Creation error message |
GPUInventory
| Attribute | Type | Description |
|---|---|---|
gpu_type |
str | GPU slug (ex: nvidia-rtx-3090) |
gpu_name |
str | Full name (ex: NVIDIA RTX 3090) |
available |
int | GPUs ready immediately (online nodes) |
on_demand |
int | GPUs startable in ~2-5 min (offline nodes) |
in_use |
int | GPUs used by active sessions |
total |
int | available + on_demand + in_use |
datacenter |
str | Datacenter name |
datacenter_code |
str | Datacenter code |
datacenter_id |
str | Datacenter UUID (for filtering) |
cluster_name |
str | Cluster name |
price_per_hour |
float | Hourly price (EUR) |
Datacenter
| Attribute | Type | Description |
|---|---|---|
datacenter_id |
str | Datacenter UUID |
name |
str | Datacenter name |
is_primary |
bool | Primary datacenter |
gpu_count |
int | Total GPUs |
LambdaResult
| Attribute | Type | Description |
|---|---|---|
success |
bool | True if exit_code == 0 |
exit_code |
int | Exit code |
stdout |
str | Standard output |
stderr |
str | Error output |
duration_seconds |
float | Total duration |
cost |
float | Cost (EUR) |
session_id |
str | Session ID used |
output_files |
list | Uploaded files |
error |
str | Error message |
QueueJob
| Attribute | Type | Description |
|---|---|---|
queue_id |
str | Job UUID |
position |
int | Queue position |
status |
str | pending, processing, completed, failed, cancelled |
status_display |
str | Status label |
gpu_config |
dict | Requested GPU configuration |
attempt_count |
int | Number of attempts |
last_attempt_at |
datetime | Last attempt date |
created_at |
datetime | Creation date |
created_session_id |
str | Created session ID (if successful) |
License
MIT License
Release files for clouditia-manager 1.18.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| clouditia_manager-1.18.0.tar.gz | 37.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| clouditia_manager-1.18.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 65.2 kB
Release files / clouditia_manager-1.18.0.tar.gz
| Download URL | clouditia_manager-1.18.0.tar.gz |
|---|---|
| Size | 37.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
6f24b77bee7d6c05646f7ebfb4a41db02c15682ad0765259705d75d870527940
|
|
BLAKE2b-256 checksum How to use checksums |
3f89076ec2592a853c9b7f488c5ad05a38f4d8312f4459d09c4c5a54ddf6386b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.3
|
Release files / clouditia_manager-1.18.0-py3-none-any.whl
| Download URL | clouditia_manager-1.18.0-py3-none-any.whl |
|---|---|
| Size | 28.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0ab7d2ebec783de265c1448c0cb4d1cb3c844ab1cb98b48f5c3af199ddb4bc38
|
|
BLAKE2b-256 checksum How to use checksums |
70aba575db537e1243a02f6fc5e1c7786f53170b3c3363b6950b433f5aa8bda0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.3
|