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. Pause & Resume sessions
Save a running session as a reusable environment (container image + workspace), then restore it later with all packages, models, and data intact.
Pause a session
env_result = manager.pause_session(
session_id="d28178b3",
name="my-vllm-env",
gpu=[{'type': 'nvidia-rtx-3090', 'count': 1}],
vcpu=16, ram=32, storage=150
)
The pause commits the container, pushes the image to the registry, and archives the workspace. This can take several minutes depending on the workspace size.
Wait for the pause to complete
import time
print("Waiting for pause to complete...")
start = time.time()
while True:
s = manager.get_session("d28178b3")
elapsed = int(time.time() - start)
mins, secs = divmod(elapsed, 60)
if s.status in ('archived', 'paused'):
print(f"Done ({s.status}) — {mins}m{secs:02d}s")
break
if s.status == 'failed':
print(f"Failed — {mins}m{secs:02d}s")
break
if elapsed % 30 == 0:
print(f" [{mins}m{secs:02d}s] status={s.status}")
time.sleep(5)
Get the saved environment ID
After the pause is complete, retrieve the environment ID:
s = manager.get_session("d28178b3")
environment_id = s.environment_id
print(f"Environment saved: {environment_id}")
Important: Always retrieve the
environment_idafter the pause is complete (status == 'paused'or'archived'). Retrieving it during the pause may return an incorrect ID.
Resume a session from saved environment
Use create_session(environment_id=...) to create a new session from the
saved environment. All packages, models, and workspace files are restored.
session = manager.create_session(
gpu_type="nvidia-rtx-3090",
environment_id=environment_id,
vcpu=8, ram=32, storage=100
)
print(f"Session ready: {session.short_id}")
Workspace restore progress
When resuming, the workspace is downloaded from S3. The SDK tracks progress:
session = manager.get_session(session.short_id)
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 |
pause_session(session_id, name, gpu, vcpu, ram, storage) |
Pause and save as environment |
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 |
environment_id |
str | Saved environment UUID (when paused/archived) |
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
Metadata
Release files for clouditia-manager 1.22.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.22.0.tar.gz | 38.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| clouditia_manager-1.22.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 67.9 kB
Release files / clouditia_manager-1.22.0.tar.gz
| Download URL | clouditia_manager-1.22.0.tar.gz |
|---|---|
| Size | 38.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a816c836d4ca0d1fbf183ab8028086d1f3e69527f13ca5b8b9b9089be74b485a
|
|
BLAKE2b-256 checksum How to use checksums |
c9cef18dc48a2d32355955bbd4a242f76f6913091ba9f7dd57f9c92bfe04d1bc
|
| 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.22.0-py3-none-any.whl
| Download URL | clouditia_manager-1.22.0-py3-none-any.whl |
|---|---|
| Size | 29.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f9002fc6a81162131fa7494e04881d8813567f1a0dfa9a2bc275ad2c38402a3a
|
|
BLAKE2b-256 checksum How to use checksums |
c4d63951beebfc6d1b3ab02f1615384178cd186b82023462ecea223718a94000
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.3
|