Clore.ai प्रदान करता है REST API जो GPU मार्केटप्लेेस तक पूर्ण प्रोग्रामेटिक पहुंच सक्षम बनाता है — सर्वर सूचीबद्ध करना, ऑर्डर बनाना, डिप्लॉयमेंट मॉनिटर करना, और रेंटल रद्द करना।
नोट: इस समय कोई आधिकारिक CLI बाइनरी उपलब्ध नहीं है। सभी ऑटोमेशन सीधे REST API के माध्यम से ऐसे टूल्स का उपयोग करके किया जाता है curl, Python, या Node.js।
बेस URL:https://api.clore.ai/v1
प्रतिक्रिया प्रारूप: JSON। प्रत्येक प्रतिक्रिया में एक शामिल होता है code फ़ील्ड जो स्थिति दर्शाता है।
स्पॉट ऑर्डर सस्ते होते हैं लेकिन बिड से बाहर हो सकते हैं। आप प्रति दिन अपनी कीमत सेट करते हैं:
ऑर्डर स्थिति जांचें
सक्रिय ऑर्डरों में शामिल हैं pub_cluster (होस्टनाम) और tcp_ports SSH एक्सेस के लिए:
अपने किराए पर लिये सर्वर में SSH करें:
ऑर्डर रद्द करें
वैकल्पिक रूप से सर्वर के साथ समस्या रिपोर्ट करें:
Python SDK
एक हल्का रैपर उपयोग करते हुए requests लाइब्रेरी। इसे इंस्टॉल करें:
CloreClient क्लास
पूर्ण कार्यशील उदाहरण
Node.js उदाहरण
नेटिव का उपयोग करते हुए fetch API (Node.js 18+):
सामान्य वर्कफ़्लो
सबसे सस्ता RTX 4090 खोजें और इसे किराए पर लें
अपने ऑर्डर मॉनिटर करें
जब कीमत X से नीचे गिरे तो ऑटो-रेंट
WebSocket
Clore.ai REST API वर्तमान में WebSocket endpoint उजागर नहीं करता है। रीयल-टाइम निगरानी के लिए, उपयुक्त अंतराल के साथ polling का उपयोग करें (नीचे दिए गए दर सीमाओं को देखें)।
दर सीमाएँ
एंडपॉइंट
सीमा
अधिकांश एंडपॉइंट
1 अनुरोध/सेकंड
create_order
1 अनुरोध/5 सेकंड
set_spot_price (मूल्य कटौती)
एक बार प्रति 600 सेकंड
दर-सीमा प्रतिक्रिया (कोड 5):
सर्वोत्तम अभ्यास:
जोड़ें time.sleep(1) लगातार API कॉल्स के बीच
के लिए create_order, अनुरोधों के बीच कम से कम 5 सेकंड प्रतीक्षा करें
मॉनिटरिंग लूप्स के लिए 60+ सेकंड के polling अंतराल का उपयोग करें
यदि आपको मार्केटप्लेस डेटा अक्सर पूछना है तो उसे स्थानीय रूप से कैश करें
Python सहायक:
त्रुटि हैंडलिंग
प्रत्येक API प्रतिक्रिया में एक code फील्ड शामिल होता है। एक मान 0 सफलता का संकेत देता है।
त्रुटि कोड
कोड
अर्थ
कदम
0
सफलता
—
1
डेटाबेस त्रुटि
देरी के बाद पुन: प्रयास करें
2
अमान्य इनपुट डेटा
अपने अनुरोध बॉडी/पैरामीटर जांचें
3
अमान्य API टोकन
डैशबोर्ड में अपना API कुंजी सत्यापित करें
4
अमान्य एंडपॉइंट
एंडपॉइंट URL जांचें
5
दर-सीमा पार हुई (1 req/sec)
अनुरोधों के बीच देरी जोड़ें
6
एप्लिकेशन त्रुटि (देखें error फील्ड)
विस्तार के लिए error फील्ड पढ़ें
कोड 6 उप-त्रुटियाँ
error मान
अर्थ
exceeded_max_step
स्पॉट मूल्य कमी बहुत अधिक; जाँचें max_step फील्ड
can_lower_every_600_seconds
स्पॉट मूल्य को फिर से कम करने से पहले प्रतीक्षा आवश्यक है; जाँचें time_to_lowering
Python त्रुटि हैंडलिंग उदाहरण
JavaScript त्रुटि हैंडलिंग उदाहरण
उपलब्ध Docker इमेजेज
Clore.ai GPU वर्कलोड के लिए अनुकूलित पूर्व-निर्मित इमेजेज प्रदान करता है:
इमेज
विवरण
cloreai/ubuntu20.04-jupyter
Ubuntu 20.04 + JupyterLab
cloreai/ubuntu22.04-jupyter
Ubuntu 22.04 + JupyterLab
आप किसी भी सार्वजनिक Docker Hub इमेज का भी उपयोग कर सकते हैं। GPU पहुँच के लिए, CUDA-सक्षम इमेजेज का उपयोग करें, उदाहरण के लिए:
पोर्ट फॉरवर्डिंग
ऑर्डर बनाते समय, एक्सपोज़ करने के लिए पोर्ट निर्दिष्ट करें:
curl -XPOST \
-H 'auth: YOUR_API_KEY' \
-H 'Content-type: application/json' \
-d '{
"id": 38,
"issue": "GPU गर्म हो रहा था और प्रदर्शन को धीमा कर रहा था"
}' \
'https://api.clore.ai/v1/cancel_order'
pip install requests
import requests
import time
class CloreClient:
"""Clore.ai REST API के लिए साधारण Python SDK."""
BASE_URL = "https://api.clore.ai/v1"
def __init__(self, api_key: str):
self.api_key = api_key
self.session = requests.Session()
self.session.headers.update({"auth": api_key})
def _get(self, endpoint: str, params: dict = None) -> dict:
url = f"{self.BASE_URL}/{endpoint}"
response = self.session.get(url, params=params)
response.raise_for_status()
data = response.json()
if data.get("code") != 0:
raise CloreAPIError(data)
return data
def _post(self, endpoint: str, body: dict) -> dict:
url = f"{self.BASE_URL}/{endpoint}"
self.session.headers.update({"Content-type": "application/json"})
response = self.session.post(url, json=body)
response.raise_for_status()
data = response.json()
if data.get("code") != 0:
raise CloreAPIError(data)
return data
def list_servers(self) -> list:
"""मार्केटप्लेस पर सभी उपलब्ध सर्वर प्राप्त करें."""
data = self._get("marketplace")
return data["servers"]
def get_server_details(self, server_id: int) -> dict:
"""किसी विशिष्ट सर्वर के लिए स्पॉट मार्केटप्लेस जानकारी प्राप्त करें."""
data = self._get("spot_marketplace", params={"market": server_id})
return data["market"]
def create_order(
self,
server_id: int,
image: str,
order_type: str = "on-demand",
currency: str = "bitcoin",
spotprice: float = None,
ports: dict = None,
ssh_password: str = None,
ssh_key: str = None,
jupyter_token: str = None,
env: dict = None,
command: str = None,
) -> dict:
"""
एक ऑन-डिमांड या स्पॉट ऑर्डर बनाएं।
आर्ग्स:
server_id: रेंट करने के लिए सर्वर का ID
image: Docker इमेज (जैसे 'cloreai/ubuntu20.04-jupyter')
order_type: 'on-demand' या 'spot'
currency: 'bitcoin' (डिफ़ॉल्ट)
spotprice: स्पॉट ऑर्डरों के लिए आवश्यक — प्रति दिन की कीमत BTC में
ports: पोर्ट फॉरवर्डिंग, उदाहरण {"22": "tcp", "8888": "http"}
ssh_password: SSH पासवर्ड (केवल अल्फ़ान्यूमेरिक अक्षर)
ssh_key: SSH पब्लिक की
jupyter_token: Jupyter नोटबुक टोकन
env: पर्यावरण चर (डिक्ट)
command: कंटेनर शुरू होने के बाद चलाने का शेल कमांड
"""
if order_type == "spot" and spotprice is None:
raise ValueError("स्पॉट ऑर्डरों के लिए spotprice आवश्यक है")
body = {
"currency": currency,
"image": image,
"renting_server": server_id,
"type": order_type,
}
if spotprice is not None:
body["spotprice"] = spotprice
if ports:
body["ports"] = ports
if ssh_password:
body["ssh_password"] = ssh_password
if ssh_key:
body["ssh_key"] = ssh_key
if jupyter_token:
body["jupyter_token"] = jupyter_token
if env:
body["env"] = env
if command:
body["command"] = command
return self._post("create_order", body)
def get_orders(self, include_completed: bool = False) -> list:
"""अपने सक्रिय (और वैकल्पिक रूप से पूर्ण) ऑर्डर प्राप्त करें."""
params = {"return_completed": "true"} if include_completed else {}
data = self._get("my_orders", params=params)
return data["orders"]
def cancel_order(self, order_id: int, issue: str = None) -> dict:
"""एक ऑर्डर रद्द करें। वैकल्पिक रूप से एक समस्या रिपोर्ट करें."""
body = {"id": order_id}
if issue:
body["issue"] = issue
return self._post("cancel_order", body)
def get_wallets(self) -> list:
"""अपने वॉलेट और बैलेंस प्राप्त करें."""
data = self._get("wallets")
return data["wallets"]
def get_my_servers(self) -> list:
"""वो सर्वर प्राप्त करें जिन्हें आप मार्केटप्लेस को प्रदान कर रहे हैं."""
data = self._get("my_servers")
return data["servers"]
class CloreAPIError(Exception):
"""जब Clore API शून्य से भिन्न कोड लौटाता है तो उठाया जाता है।"""
ERROR_CODES = {
0: "सामान्य",
1: "डेटाबेस त्रुटि",
2: "अमान्य इनपुट डेटा",
3: "अमान्य API टोकन",
4: "अमान्य अंतबिंदु",
5: "रेट लिमिट पार (1 req/sec)",
6: "त्रुटि (त्रुटि फ़ील्ड देखें)",
}
def __init__(self, response: dict):
self.code = response.get("code")
self.error = response.get("error", "")
message = self.ERROR_CODES.get(self.code, f"Unknown code {self.code}")
if self.error:
message = f"{message}: {self.error}"
super().__init__(f"Clore API error {self.code}: {message}")
import os
from clore_client import CloreClient, CloreAPIError
# क्लाइंट इनिशियलाइज़ करें
client = CloreClient(api_key=os.environ["CLORE_API_KEY"])
# 1. मार्केटप्लेस ब्राउज़ करें
servers = client.list_servers()
print(f"Marketplace पर {len(servers)} सर्वर मिले")
# 2. उपलब्ध RTX 4090 सर्वरों को फ़िल्टर करें
rtx4090_servers = [
s for s in servers
if "4090" in s["specs"].get("gpu", "") and not s["rented"]
]
if not rtx4090_servers:
print("कोई उपलब्ध RTX 4090 सर्वर नहीं मिला")
exit(1)
# 3. सबसे सस्ता चुनें
cheapest = min(rtx4090_servers, key=lambda s: s["price"]["on_demand"]["bitcoin"])
print(f"सबसे सस्ता RTX 4090: सर्वर ID {cheapest['id']}, "
f"कीमत {cheapest['price']['on_demand']['bitcoin']:.8f} BTC/दिन")
# 4. एक ऑर्डर बनाएं
try:
client.create_order(
server_id=cheapest["id"],
image="cloreai/ubuntu20.04-jupyter",
order_type="on-demand",
currency="bitcoin",
ports={"22": "tcp", "8888": "http"},
ssh_password="SecurePass123",
jupyter_token="MyToken123",
)
print("ऑर्डर सफलतापूर्वक बनाया गया!")
except CloreAPIError as e:
print(f"ऑर्डर बनाने में विफल: {e}")
exit(1)
# 5. अपने ऑर्डर जांचें
orders = client.get_orders()
for order in orders:
if not order.get("expired"):
cluster = order.get("pub_cluster", [])
tcp = order.get("tcp_ports", [])
print(f"ऑर्डर {order['id']}: सर्वर {order['si']}")
if cluster and tcp:
ssh_port = tcp[0].split(":")[1]
print(f" SSH: ssh root@{cluster[0]} -p {ssh_port}")
from clore_client import CloreClient
client = CloreClient(api_key="YOUR_API_KEY")
def rent_cheapest_rtx4090(image="cloreai/ubuntu20.04-jupyter", ssh_password="SecurePass123"):
servers = client.list_servers()
# फ़िल्टर: उपलब्ध RTX 4090
candidates = [
s for s in servers
if "4090" in s["specs"].get("gpu", "")
and not s["rented"]
]
if not candidates:
raise RuntimeError("कोई उपलब्ध RTX 4090 सर्वर नहीं मिला")
# ऑन-डिमांड BTC कीमत के अनुसार सॉर्ट करें
candidates.sort(key=lambda s: s["price"]["on_demand"]["bitcoin"])
best = candidates[0]
price_btc = best["price"]["on_demand"]["bitcoin"]
print(f"सर्वर रेंट कर रहे हैं {best['id']}: {best['specs']['gpu']} @ {price_btc:.8f} BTC/दिन")
client.create_order(
server_id=best["id"],
image=image,
order_type="on-demand",
currency="bitcoin",
ports={"22": "tcp"},
ssh_password=ssh_password,
)
print("हो गया! SSH कनेक्शन विवरण के लिए अपने ऑर्डर चेक करें.")
return best["id"]
rent_cheapest_rtx4090()
import time
from clore_client import CloreClient
client = CloreClient(api_key="YOUR_API_KEY")
def monitor_orders(poll_interval_seconds=60):
"""ऑर्डरों को पोल करें और स्थिति अपडेट प्रिंट करें."""
print(f"ऑर्डरों की निगरानी (हर {poll_interval_seconds}s पर पोल किया जा रहा है). रोकने के लिए Ctrl+C.\n")
while True:
orders = client.get_orders(include_completed=False)
active = [o for o in orders if not o.get("expired")]
print(f"--- {len(active)} सक्रिय ऑर्डर(स) ---")
for order in active:
cluster = order.get("pub_cluster", [])
tcp = order.get("tcp_ports", [])
spend = order.get("spend", 0)
ssh_info = ""
if cluster and tcp:
port = tcp[0].split(":")[1]
ssh_info = f" | SSH: {cluster[0]}:{port}"
print(f" ऑर्डर {order['id']}: सर्वर {order['si']}"
f" | खर्च {spend:.8f} BTC{ssh_info}")
if not active:
print(" कोई सक्रिय ऑर्डर नहीं है.")
print()
time.sleep(poll_interval_seconds)
monitor_orders()
import time
from clore_client import CloreClient
client = CloreClient(api_key="YOUR_API_KEY")
def auto_rent_on_price_drop(
gpu_model: str = "RTX 4090",
max_price_btc: float = 0.00015,
image: str = "cloreai/ubuntu20.04-jupyter",
ssh_password: str = "SecurePass123",
check_interval_seconds: int = 120,
):
"""
मार्केटप्लेस देखें और जब कीमत संकेतक से नीचे गिरे तो GPU को ऑटो-रेंट करें।
आर्ग्स:
gpu_model: खोजने के लिए GPU नाम (केस-इन्सेंसिटिव)
max_price_btc: BTC में प्रति दिन अधिकतम स्वीकार्य कीमत
image: डिप्लॉय करने के लिए Docker इमेज
ssh_password: कंटेनर के लिए SSH पासवर्ड
check_interval_seconds: कितनी बार जांचें (रेट लिमिट का सम्मान करें!)
"""
print(f"{gpu_model} के लिए देख रहे हैं ≤ {max_price_btc:.8f} BTC/दिन...")
while True:
servers = client.list_servers()
for server in servers:
gpu = server["specs"].get("gpu", "")
if gpu_model.lower() not in gpu.lower():
continue
if server["rented"]:
continue
price = server["price"]["on_demand"]["bitcoin"]
if price <= max_price_btc:
print(f"🎯 मैच मिला! सर्वर {server['id']}: {gpu} @ {price:.8f} BTC/दिन")
try:
client.create_order(
server_id=server["id"],
image=image,
order_type="on-demand",
currency="bitcoin",
ports={"22": "tcp"},
ssh_password=ssh_password,
required_price=price, # इस कीमत को लॉक करें
)
print(f"✅ सर्वर {server['id']} के लिए ऑर्डर बनाया गया!")
return server["id"]
except Exception as e:
print(f"Failed to create order: {e}. Will retry...")
print(f"No match yet. Checking again in {check_interval_seconds}s...")
time.sleep(check_interval_seconds)
auto_rent_on_price_drop(gpu_model="4090", max_price_btc=0.00012)
{ "code": 5 }
import time
def safe_api_call(fn, *args, delay=1.1, **kwargs):
"""एक API कॉल को दर-सीमा सुरक्षा के साथ रैप करें."""
result = fn(*args, **kwargs)
time.sleep(delay)
return result
from clore_client import CloreClient, CloreAPIError
import time
client = CloreClient(api_key="YOUR_API_KEY")
def create_order_with_retry(server_id, image, max_retries=3):
for attempt in range(max_retries):
try:
return client.create_order(
server_id=server_id,
image=image,
order_type="on-demand",
currency="bitcoin",
ports={"22": "tcp"},
ssh_password="SecurePass123",
)
except CloreAPIError as e:
if e.code == 5: # Rate limit
print(f"Rate limited. Waiting 5s... (attempt {attempt+1}/{max_retries})")
time.sleep(5)
elif e.code == 3: # Bad API key
print("Invalid API key! Check your CLORE_API_KEY.")
raise
elif e.code == 2: # Bad input
print(f"Invalid request: {e}")
raise
else:
print(f"API error: {e}. Retrying in 3s...")
time.sleep(3)
raise RuntimeError(f"Failed after {max_retries} attempts")
async function createOrderWithRetry(client, serverConfig, maxRetries = 3) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
return await client.createOrder(serverConfig);
} catch (err) {
const code = parseInt(err.message.match(/error (\d+)/)?.[1]);
if (code === 5) {
console.log(`Rate limited. Waiting 5s... (attempt ${attempt + 1}/${maxRetries})`);
await new Promise(r => setTimeout(r, 5000));
} else if (code === 3) {
throw new Error('Invalid API key');
} else {
console.log(`API error: ${err.message}. Retrying in 3s...`);
await new Promise(r => setTimeout(r, 3000));
}
}
}
throw new Error(`Failed after ${maxRetries} attempts`);
}