Skip to content

Show instance availability #4

Description

@Hegghammer

It would be great if the CLI could show currently available instances. I often get errors like this: "API error 503: Not enough resources to deploy a 1 GPU instance type 1V100.6V in FIN-03" -- and there is currently no easy way to find out what is available where at any given time.

I built a temporary workaround with the Python SDK (see below), but I would prefer to have it implemented in the CLI.

#!/usr/bin/env python3
"""Show currently available Verda instance types in the terminal.

Verda has a CLI (https://github.com/verda-cloud/verda-cli), but it does not
currently show live instance availability.

This script uses the Verda Python SDK
(https://github.com/verda-cloud/sdk-python) to query instance types and current
availability directly

By default, the output is filtered to GPU instances only. Use `-a`/`--all` to
show CPU-only instances as well, and `-l`/`--location` to restrict results to a
single datacenter.

Usage:
- python3 08_sandbox/verda_available.py
- python3 08_sandbox/verda_available.py --all
- python3 08_sandbox/verda_available.py --location FIN-01
- python3 08_sandbox/verda_available.py -a -l FIN-01

The script does not aggregate locations into a single row. For example, if the 
same instance type is available in FIN-01 and FIN-02, it will appear twice in 
the output, once for each datacenter.
"""

import argparse
from datetime import datetime
import os
import pandas as pd
from verda import VerdaClient


def parse_args():
    parser = argparse.ArgumentParser(
        description="Show currently available Verda instance types."
    )
    parser.add_argument(
        "-a",
        "--all",
        action="store_true",
        help="Show CPU-only instances too (default: GPU instances only).",
    )
    parser.add_argument(
        "-l", "--location", help="Filter to a specific Verda location code."
    )
    return parser.parse_args()


args = parse_args()

CLIENT_SECRET = os.environ["VERDA_CLIENT_SECRET"]
CLIENT_ID = os.environ["VERDA_CLIENT_ID"]
client = VerdaClient(CLIENT_ID, CLIENT_SECRET)

# Get all instance types with specs
instance_types = client.instance_types.get()
all_types = {}
for t in instance_types:
    all_types[t.instance_type] = {
        "name": t.name,
        "cpu_cores": t.cpu["number_of_cores"],
        "gpu": t.gpu["description"],
        "gpu_count": t.gpu["number_of_gpus"],
        "ram_gb": t.memory["size_in_gigabytes"],
        "vram_gb": t.gpu_memory["size_in_gigabytes"],
        "price_hour": t.price_per_hour,
        "spot_price": t.spot_price_per_hour,
    }

# Get availability by location
availabilities = client.instances.get_availabilities()

# Build DataFrame with only available instances
data = []
for avail in availabilities:
    loc = avail["location_code"]
    for instance_type in avail["availabilities"]:
        if instance_type in all_types:
            specs = all_types[instance_type]
            data.append(
                {
                    "location": loc,
                    "instance_type": instance_type,
                    "name": specs["name"],
                    "cpu_cores": specs["cpu_cores"],
                    "ram_gb": specs["ram_gb"],
                    "gpu": specs["gpu"],
                    "vram_gb": specs["vram_gb"],
                    "price_hour": specs["price_hour"],
                    "spot_price": specs["spot_price"],
                }
            )

df = pd.DataFrame(data)

if args.location:
    df = df[df["location"].str.lower() == args.location.lower()]

if not args.all:
    df = df[
        df["gpu"].str.contains("GPU|RTX|A100|H100|L40|B300|V100", case=False, na=False)
    ]

df = df.sort_values("price_hour")

if df.empty:
    filters = []
    if not args.all:
        filters.append("GPU instances only")
    if args.location:
        filters.append(f"location={args.location}")
    suffix = f" for {' and '.join(filters)}" if filters else ""
    raise SystemExit(f"No available instances found{suffix}.")

# Display in terminal
timestamp = datetime.now().astimezone().strftime("%Y-%m-%d %H:%M:%S %Z")
print()
print(f"Verda instances available at {timestamp}:")
print()
print(
    df[
        [
            "location",
            "instance_type",
            "gpu",
            "vram_gb",
            "price_hour",
            "spot_price",
        ]
    ].to_markdown(index=False, tablefmt="grid")
)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions