# Quick Start: Rent Your First GPU

## What We're Building

A Python script that finds an available GPU server, rents it, connects via SSH, runs a CUDA test, and releases the resources — all in under 5 minutes.

## Prerequisites

* Clore.ai account with API key ([get one here](https://clore.ai))
* Python 3.10+
* `requests` library (`pip install requests`)
* SSH client

## Step 1: Set Up the Clore Client

> 📦 **Using the standard Clore API client.** See [Clore API Client Reference](/reference/clore-client.md) for the full implementation and setup instructions. Save it as `clore_client.py` in your project.

```python
from clore_client import CloreClient

client = CloreClient(api_key="your-api-key")
```

## Step 2: Find an Available GPU

```python
# find_gpu.py
from clore_client import CloreClient

def find_cheapest_gpu(client: CloreClient, gpu_type: str = "RTX 4090", 
                       max_price_usd: float = 0.50) -> dict:
    """Find the cheapest available GPU of specified type."""
    
    servers = client.get_marketplace()
    
    # Filter: available, matches GPU type, within price range
    candidates = []
    for server in servers:
        if server.get("rented"):
            continue
        
        gpu_array = server.get("gpu_array", [])
        if not any(gpu_type in gpu for gpu in gpu_array):
            continue
        
        # Get USD price (on-demand)
        price_usd = server.get("price", {}).get("usd", {}).get("on_demand_clore")
        if price_usd and price_usd <= max_price_usd:
            candidates.append({
                "id": server["id"],
                "gpus": gpu_array,
                "price_usd": price_usd,
                "reliability": server.get("reliability", 0),
                "specs": server.get("specs", {})
            })
    
    if not candidates:
        raise Exception(f"No {gpu_type} available under ${max_price_usd}/hr")
    
    # Sort by price, then reliability
    candidates.sort(key=lambda x: (x["price_usd"], -x["reliability"]))
    
    return candidates[0]

if __name__ == "__main__":
    client = CloreClient("YOUR_API_KEY")
    
    gpu = find_cheapest_gpu(client, "RTX 4090", max_price_usd=0.50)
    print(f"Found: Server {gpu['id']}")
    print(f"GPUs: {gpu['gpus']}")
    print(f"Price: ${gpu['price_usd']:.2f}/hr")
    print(f"Reliability: {gpu['reliability']}%")
```

## Step 3: Rent the GPU

```python
# rent_gpu.py
import time
from clore_client import CloreClient
from find_gpu import find_cheapest_gpu

def rent_gpu(client: CloreClient, server_id: int, ssh_password: str) -> dict:
    """Rent a GPU server and wait for it to be ready."""
    
    print(f"Creating order for server {server_id}...")
    
    order = client.create_order(
        server_id=server_id,
        image="nvidia/cuda:12.8.0-base-ubuntu22.04",
        order_type="on-demand",
        currency="CLORE-Blockchain",
        ssh_password=ssh_password,
        ports={"22": "tcp", "8888": "http"},
        env={"NVIDIA_VISIBLE_DEVICES": "all"}
    )
    
    order_id = order["order_id"]
    print(f"Order created: {order_id}")
    
    # Wait for order to become active
    print("Waiting for server to start...")
    for _ in range(60):  # Max 2 minutes
        orders = client.get_orders()
        current = next((o for o in orders if o["order_id"] == order_id), None)
        
        if current and current.get("status") == "running":
            return current
        
        time.sleep(2)
    
    raise Exception("Timeout waiting for server to start")

if __name__ == "__main__":
    client = CloreClient("YOUR_API_KEY")
    
    # Find cheapest RTX 4090
    gpu = find_cheapest_gpu(client, "RTX 4090", max_price_usd=0.50)
    print(f"Selected server {gpu['id']} at ${gpu['price_usd']:.2f}/hr")
    
    # Rent it
    order = rent_gpu(client, gpu["id"], ssh_password="MySecurePass123!")
    
    print("\n✅ Server is ready!")
    print(f"SSH: {order['connection']['ssh']}")
    print(f"Order ID: {order['order_id']}")
```

## Step 4: Connect and Run CUDA Test

```python
# test_gpu.py
import subprocess
import sys

def run_cuda_test(ssh_host: str, ssh_port: int, password: str):
    """Connect via SSH and run nvidia-smi."""
    
    # Using sshpass for password auth (install: apt install sshpass)
    ssh_cmd = f"""sshpass -p '{password}' ssh -o StrictHostKeyChecking=no \
        -p {ssh_port} root@{ssh_host} \
        'nvidia-smi && python3 -c "import torch; print(f\"CUDA available: {torch.cuda.is_available()}\")"'
    """
    
    print("Connecting and testing GPU...")
    result = subprocess.run(ssh_cmd, shell=True, capture_output=True, text=True)
    
    if result.returncode == 0:
        print(result.stdout)
    else:
        print(f"Error: {result.stderr}")
        
if __name__ == "__main__":
    # Parse SSH connection string like "ssh root@host -p 12345"
    # From order["connection"]["ssh"]
    ssh_host = sys.argv[1] if len(sys.argv) > 1 else "example.clore.ai"
    ssh_port = int(sys.argv[2]) if len(sys.argv) > 2 else 22
    password = sys.argv[3] if len(sys.argv) > 3 else "MySecurePass123!"
    
    run_cuda_test(ssh_host, ssh_port, password)
```

## Step 5: Clean Up

```python
# cleanup.py
from clore_client import CloreClient

def cleanup_order(client: CloreClient, order_id: int):
    """Cancel order and show final cost."""
    
    # Get order details before canceling
    orders = client.get_orders()
    order = next((o for o in orders if o["order_id"] == order_id), None)
    
    if not order:
        print(f"Order {order_id} not found")
        return
    
    # Calculate duration
    duration_minutes = (order.get("ended", 0) - order.get("started", 0)) / 60
    if duration_minutes <= 0:
        import time
        duration_minutes = (time.time() - order.get("started", 0)) / 60
    
    # Cancel
    client.cancel_order(order_id)
    print(f"✅ Order {order_id} cancelled")
    print(f"Duration: {duration_minutes:.1f} minutes")
    print(f"Estimated cost: ~${order.get('price', 0) * duration_minutes / 60:.4f}")

if __name__ == "__main__":
    import sys
    client = CloreClient("YOUR_API_KEY")
    order_id = int(sys.argv[1]) if len(sys.argv) > 1 else 12345
    cleanup_order(client, order_id)
```

## Full Script: End-to-End GPU Rental

```python
#!/usr/bin/env python3
"""
Complete GPU rental workflow: Find → Rent → Test → Cleanup
Usage: python quick_start.py YOUR_API_KEY
"""

import requests
import time
import subprocess
import sys
from typing import Optional, Dict, Any, List

def find_cheapest_gpu(client: CloreClient, gpu_type: str = "RTX", 
                       max_price_usd: float = 1.0) -> dict:
    """Find cheapest available GPU."""
    servers = client.get_marketplace()
    
    candidates = []
    for s in servers:
        if s.get("rented"):
            continue
        gpus = s.get("gpu_array", [])
        if not any(gpu_type in g for g in gpus):
            continue
        price = s.get("price", {}).get("usd", {}).get("on_demand_clore")
        if price and price <= max_price_usd:
            candidates.append({"id": s["id"], "gpus": gpus, "price": price})
    
    if not candidates:
        raise Exception(f"No {gpu_type} GPU under ${max_price_usd}/hr")
    
    return min(candidates, key=lambda x: x["price"])

def wait_for_ready(client: CloreClient, order_id: int, timeout: int = 120) -> dict:
    """Wait for order to become active."""
    for _ in range(timeout // 2):
        orders = client.get_orders()
        order = next((o for o in orders if o["order_id"] == order_id), None)
        if order and order.get("status") == "running":
            return order
        time.sleep(2)
    raise Exception("Timeout waiting for server")

def main():
    if len(sys.argv) < 2:
        print("Usage: python quick_start.py YOUR_API_KEY")
        sys.exit(1)
    
    api_key = sys.argv[1]
    ssh_password = "CloreQuickStart123!"
    
    client = CloreClient(api_key)
    
    # Check balance
    print("💰 Checking balance...")
    wallets = client.get_wallets()
    clore_balance = next((w["balance"] for w in wallets if "CLORE" in w["name"]), 0)
    print(f"   CLORE balance: {clore_balance:.2f}")
    
    if clore_balance < 5:
        print("❌ Insufficient balance (need at least 5 CLORE)")
        sys.exit(1)
    
    # Find GPU
    print("\n🔍 Finding cheapest GPU...")
    try:
        gpu = find_cheapest_gpu(client, "RTX", max_price_usd=0.80)
    except Exception as e:
        gpu = find_cheapest_gpu(client, "GTX", max_price_usd=0.50)
    
    print(f"   Found: Server {gpu['id']}")
    print(f"   GPUs: {', '.join(gpu['gpus'])}")
    print(f"   Price: ${gpu['price']:.2f}/hr")
    
    # Rent
    print("\n🚀 Creating rental order...")
    order = client.create_order(
        gpu["id"],
        ssh_password=ssh_password,
        ports={"22": "tcp"}
    )
    order_id = order["order_id"]
    print(f"   Order ID: {order_id}")
    
    # Wait
    print("\n⏳ Waiting for server to start...")
    active_order = wait_for_ready(client, order_id)
    
    ssh_info = active_order["connection"]["ssh"]
    print(f"\n✅ Server ready!")
    print(f"   SSH: {ssh_info}")
    print(f"   Password: {ssh_password}")
    
    # Quick test
    print("\n🧪 Running GPU test...")
    print("   (Connect manually and run: nvidia-smi)")
    
    # Prompt for cleanup
    input("\n⏸️  Press Enter to cancel order and clean up...")
    
    # Cleanup
    print("\n🧹 Cancelling order...")
    client.cancel_order(order_id)
    print("   Done!")
    
    # Final stats
    duration = (time.time() - active_order.get("started", time.time())) / 60
    cost = gpu["price"] * duration / 60
    print(f"\n📊 Summary:")
    print(f"   Duration: {duration:.1f} minutes")
    print(f"   Estimated cost: ${cost:.4f}")

if __name__ == "__main__":
    main()
```

## Running the Script

```bash
# Install dependencies
pip install requests

# Run
python quick_start.py YOUR_API_KEY

## Cost Comparison

| GPU | Clore.ai | AWS | Savings |
|-----|----------|-----|---------|
| RTX 4090 | ~$0.35/hr | N/A | ∞ |
| A100 40GB | ~$1.50/hr | ~$4.10/hr | 63% |
| RTX 3090 | ~$0.20/hr | N/A | ∞ |

> 💡 For a full breakdown of GPU cloud pricing across providers, see [Cheapest GPU Cloud in 2026: Clore.ai vs Vast.ai vs RunPod](https://blog.clore.ai/cheapest-gpu-cloud-in-2026-cloreai-vs-vastai-vs-runpod-honest-comparison/)

## Next Steps

- [Setting Up Your Development Environment](dev-environment.md)
- [Automating GPU Rental with Python](automation-basics.md)
- [Understanding Spot vs On-Demand](spot-vs-ondemand.md)
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://dev.clore.ai/getting-started/quick-start.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
