# Python SDK गाइड

{% hint style="success" %}
**SDK में नया?** शुरू करें [5-मिनट त्वरित आरंभ](https://docs.clore.ai/guides/guides_v2-hi/getting-started/python-quickstart) पहले।
{% endhint %}

वास्तविक उदाहरणों के साथ एक त्वरित-शुरुआत ट्यूटोरियल के लिए देखें [Clore.ai Python SDK — 5 मिनट में अपने GPU वर्कफ़्लो को स्वचालित करें](https://blog.clore.ai/cloreai-python-sdk-automate-your-gpu-workflows-in-5-minutes/)

## स्थापना

```bash
pip install clore-ai
```

SDK दो क्लाइंट प्रदान करता है:

* **`CloreAI`** — समकालिक (सरल, स्क्रिप्ट्स के लिए अच्छा)
* **`AsyncCloreAI`** — असंबद्ध (एक साथ कई ऑपरेशन के लिए तेज़)

दोनों समान विधियों को साझा करते हैं और समान Pydantic मॉडल लौटाते हैं।

***

## सिंक बनाम Async — कब किसका उपयोग करें

| उपयोग का मामला                 | क्लाइंट        | क्यों                          |
| ------------------------------ | -------------- | ------------------------------ |
| सरल स्क्रिप्ट्स, एकबारगी कार्य | `CloreAI`      | सरल कोड, नहीं `async/await`    |
| मॉनिटरिंग लूप्स                | `CloreAI`      | क्रमिक जांचें ठीक काम करती हैं |
| बुल्क मार्केटप्लेस क्वेरीज़    | `AsyncCloreAI` | समानांतर अनुरोध = तेज़         |
| बैच ऑर्डर निर्माण              | `AsyncCloreAI` | एक साथ कई ऑर्डर बनाएं          |
| वेब अनुप्रयोग                  | `AsyncCloreAI` | नॉन-ब्लॉकिंग I/O               |

### सिंक उदाहरण

```python
from clore_ai import CloreAI

client = CloreAI()  # CLORE_API_KEY एनव वेरिएबल का उपयोग करता है

servers = client.marketplace(gpu="RTX 4090")
print(f"Found {len(servers)} servers")

client.close()  # या कंटेक्स्ट मैनेजर का उपयोग करें
```

### Async उदाहरण

```python
import asyncio
from clore_ai import AsyncCloreAI

async def main():
    async with AsyncCloreAI() as client:
        servers = await client.marketplace(gpu="RTX 4090")
        print(f"Found {len(servers)} servers")

asyncio.run(main())
```

### कॉन्टेक्स्ट मैनेजर (अनुशंसित)

ऑटोमैटिक क्लीनअप के लिए दोनों क्लाइंट कॉन्टेक्स्ट मैनेजर को सपोर्ट करते हैं:

```python
# सिंक
with CloreAI() as client:
    wallets = client.wallets()

# Async
async with AsyncCloreAI() as client:
    wallets = await client.wallets()
```

***

## क्लाइंट कॉन्फ़िगरेशन

```python
client = CloreAI(
    api_key="your_key",      # या CLORE_API_KEY एनव वेरिएबल सेट करें
    base_url="https://api.clore.ai/v1",  # कस्टम API एंडपॉइंट
    timeout=30.0,            # अनुरोध का टाइमआउट सेकंड में
    max_retries=3            # रेट लिमिट / नेटवर्क त्रुटियों पर पुन: प्रयास
)
```

SDK में इन-बिल्ट रेट लिमिटर शामिल है:

* **सामान्य अनुरोध:** 1 अनुरोध/सेकंड
* **`create_order`:** कॉल्स के बीच 5-सेकंड कूलडाउन
* **रेट लिमिट त्रुटियाँ (कोड 5):** स्वचालित एक्सपोनेंशियल बैकऑफ

***

## मार्केटप्लेस फ़िल्टरिंग

यह `marketplace()` मेथड सभी उपलब्ध सर्वरों को फेच करती है और क्लाइंट-साइड पर फ़िल्टर करती है:

```python
from clore_ai import CloreAI

client = CloreAI()

# सभी उपलब्ध सर्वर
all_servers = client.marketplace()

# GPU मॉडल द्वारा फ़िल्टर करें (केस-इनसेंसिटिव सबस्ट्रिंग मैच)
rtx_4090s = client.marketplace(gpu="RTX 4090")

# कई मानदंडों द्वारा फ़िल्टर करें
budget_gpus = client.marketplace(
    gpu="RTX 4090",
    max_price_usd=1.0,       # अधिकतम $1.00/घंटा
    min_gpu_count=2,          # कम से कम 2 GPUs
    min_ram_gb=64.0,          # कम से कम 64GB सिस्टम RAM
    available_only=True       # केवल उपलब्ध सर्वर (डिफ़ॉल्ट)
)
```

### उन्नत फ़िल्टरिंग (क्लाइंट-साइड)

मेथड में न बने फ़िल्टरों के लिए, लौटाए गए `Server` ऑब्जेक्ट्स को स्वयं फ़िल्टर करें:

```python
servers = client.marketplace(gpu="RTX 4090")

# उच्च विश्वसनीयता वाले EU के सर्वर
eu_servers = [
    s for s in servers
    if s.location and s.location.upper() in ("DE", "FR", "NL", "FI")
    and s.reliability and s.reliability >= 0.95
]

# कीमत के अनुसार सॉर्ट करें
cheapest = sorted(servers, key=lambda s: s.price_usd or float("inf"))
print(f"Cheapest: Server {cheapest[0].id} — ${cheapest[0].price_usd:.4f}/h")
```

### सर्वर मॉडल फ़ील्ड्स

प्रत्येक `MarketplaceServer` ऑब्जेक्ट में ये गुण और सुविधाजनक प्रॉपर्टीज़ होती हैं:

| फ़ील्ड           | प्रकार                | विवरण                                                             |
| ---------------- | --------------------- | ----------------------------------------------------------------- |
| `id`             | `int`                 | सर्वर ID (इसे उपयोग करें `create_order`)                          |
| `gpu_model`      | `str \| None`         | स्पेसिफ़िकेशन से GPU विवरण (प्रॉपर्टी)                            |
| `gpu_count`      | `int`                 | GPU की संख्या से `gpu_array` (प्रॉपर्टी)                          |
| `ram_gb`         | `float \| None`       | GB में सिस्टम RAM (प्रॉपर्टी, से) `specs.ram`)                    |
| `price_usd`      | `float \| None`       | USD में ऑन-डिमांड कीमत (प्रॉपर्टी, से) `price.usd.on_demand_usd`) |
| `spot_price_usd` | `float \| None`       | USD में स्पॉट कीमत (प्रॉपर्टी)                                    |
| `available`      | `bool`                | क्या सर्वर रेंट पर नहीं है (प्रॉपर्टी)                            |
| `location`       | `str \| None`         | नेटवर्क स्पेसिफ़िकेशन से कंट्री कोड (प्रॉपर्टी)                   |
| `specs`          | `ServerSpecs \| None` | हार्डवेयर स्पेसिफ़िकेशन (cpu, ram, disk, gpu, net)                |
| `price`          | `ServerPrice \| None` | पूर्ण प्राइसिंग संरचना                                            |
| `rented`         | `bool \| None`        | क्या सर्वर वर्तमान में किराए पर है                                |

***

## ऑर्डर प्रबंधन

### ऑर्डर बनाना

```python
order = client.create_order(
    server_id=142,
    image="cloreai/ubuntu22.04-cuda12",
    type="on-demand",               # "on-demand" या "spot"
    currency="bitcoin",             # भुगतान मुद्रा
    ssh_password="MySecurePass",    # SSH एक्सेस
    ports={"22": "tcp", "8888": "http"},  # पोर्ट मैपिंग्स
    env={"HF_TOKEN": "hf_xxx"},    # पर्यावरण वेरिएबल
    command="bash /start.sh",       # कस्टम स्टार्टअप कमांड
    jupyter_token="my_token"        # Jupyter नोटबुक टोकन
)

print(f"Order ID: {order.id}")
print(f"IP: {order.pub_cluster}")
print(f"Ports: {order.tcp_ports}")
```

### पूर्ण `create_order` पैरामीटर्स

| पैरामीटर             | प्रकार  | आवश्यक | विवरण                             |
| -------------------- | ------- | ------ | --------------------------------- |
| `server_id`          | `int`   | ✅      | किराए पर लेने के लिए सर्वर        |
| `image`              | `str`   | ✅      | डॉकर इमेज                         |
| `type`               | `str`   | ✅      | `"on-demand"` या `"spot"`         |
| `currency`           | `str`   | ✅      | भुगतान मुद्रा (उदा., `"bitcoin"`) |
| `ssh_password`       | `str`   | —      | SSH पासवर्ड                       |
| `ssh_key`            | `str`   | —      | SSH सार्वजनिक कुंजी               |
| `ports`              | `dict`  | —      | पोर्ट मैपिंग्स (`{"22": "tcp"}`)  |
| `env`                | `dict`  | —      | पर्यावरण वेरिएबल                  |
| `jupyter_token`      | `str`   | —      | Jupyter नोटबुक टोकन               |
| `command`            | `str`   | —      | स्टार्टअप कमांड                   |
| `spot_price`         | `float` | —      | स्पॉट बोली की कीमत                |
| `required_price`     | `float` | —      | आवश्यक कीमत                       |
| `autossh_entrypoint` | `str`   | —      | ऑटो SSH एंट्रीपॉइंट               |

### लिस्टिंग ऑर्डर्स

```python
# केवल सक्रिय ऑर्डर
active = client.my_orders()
for o in active:
    print(f"Order {o.id}: type={o.type}, IP={o.pub_cluster}, status={o.status}")

# पूर्ण ऑर्डर्स शामिल करें
all_orders = client.my_orders(include_completed=True)
```

### ऑर्डर मॉडल फ़ील्ड्स

| फ़ील्ड        | प्रकार          | विवरण                                  |
| ------------- | --------------- | -------------------------------------- |
| `id`          | `int`           | ऑर्डर ID                               |
| `server_id`   | `int \| None`   | किराए पर लिया गया सर्वर ID             |
| `type`        | `str`           | `"on-demand"` या `"spot"`              |
| `status`      | `str \| None`   | ऑर्डर स्थिति                           |
| `image`       | `str \| None`   | डॉकर इमेज                              |
| `currency`    | `str \| None`   | भुगतान मुद्रा                          |
| `price`       | `float \| None` | कीमत                                   |
| `pub_cluster` | `str \| None`   | पब्लिक IP / होस्टनाम                   |
| `tcp_ports`   | `dict \| None`  | पोर्ट मैपिंग्स (उदा., `{"22": 50022}`) |
| `created_at`  | `str \| None`   | निर्माण टाइमस्टैम्प                    |

### ऑर्डर्स की निगरानी

```python
import time

def wait_for_ready(client, order_id, timeout=120):
    """एक ऑर्डर के सार्वजनिक IP मिलने तक प्रतीक्षा करें।"""
    for _ in range(timeout // 10):
        orders = client.my_orders()
        order = next((o for o in orders if o.id == order_id), None)
        if order and order.pub_cluster:
            return order
        time.sleep(10)
    raise TimeoutError(f"Order {order_id} not ready after {timeout}s")

# उपयोग
order = client.create_order(server_id=142, image="cloreai/ubuntu22.04-cuda12", type="on-demand", currency="bitcoin")
ready = wait_for_ready(client, order.id)
print(f"SSH: ssh root@{ready.pub_cluster} -p {ready.tcp_ports.get('22', 22)}")
```

### ऑर्डर्स रद्द करना

```python
# वैकल्पिक कारण के साथ रद्द करें
client.cancel_order(order_id=38, issue="Job complete")

# सभी सक्रिय ऑर्डर रद्द करें
orders = client.my_orders()
for order in orders:
    client.cancel_order(order.id, issue="Cleanup")
    print(f"Cancelled order {order.id}")
```

***

## सर्वर प्रबंधन (होस्टर्स के लिए)

यदि आप Clore पर GPUs होस्ट करते हैं, तो SDK आपको अपने सर्वरों का प्रबंधन करने देता है:

### अपने सर्वर सूचीबद्ध करें

```python
my_servers = client.my_servers()
for s in my_servers:
    print(f"Server {s.id}: {s.gpu_model} — {s.status}")
```

### सर्वर कॉन्फ़िग प्राप्त करें

```python
config = client.server_config("MyGPU-Rig")
print(f"Name: {config.name}")
print(f"Visibility: {config.visibility}")
print(f"Online: {config.online}")
print(f"Min rental: {config.mrl}h")
print(f"On-demand price: {config.on_demand_price}")
print(f"Spot price: {config.spot_price}")
```

### सर्वर सेटिंग्स अपडेट करें

```python
client.set_server_settings(
    name="MyGPU-Rig",
    availability=True,       # सर्वर को उपलब्ध बनाएं
    mrl=24,                  # न्यूनतम 24 घँटे किराया
    on_demand=0.0001,        # ऑन-डिमांड कीमत BTC में
    spot=0.00000113          # स्पॉट कीमत BTC में
)
print("Settings updated")
```

***

## स्पॉट मार्केट

स्पॉट ऑर्डर 30–50% सस्ते होते हैं पर यदि कोई आपसे अधिक बोली लगाता है तो इन्हें इंटरप्ट किया जा सकता है।

### स्पॉट ऑफ़र देखें

```python
offers = client.spot_marketplace(server_id=6)
for offer in offers:
    print(f"Order {offer.get('order_id')}: price={offer.get('price')}")
```

### स्पॉट ऑर्डर बनाएं

```python
order = client.create_order(
    server_id=142,
    image="cloreai/ubuntu22.04-cuda12",
    type="spot",
    currency="bitcoin",
    spot_price=0.0001,       # आपकी बोली की कीमत
    ssh_password="MyPass"
)
print(f"Spot order {order.id} created")
```

### स्पॉट कीमत समायोजित करें

```python
# आउटबिडिंग से बचने के लिए अपनी बोली बढ़ाएँ
client.set_spot_price(order_id=39, price=0.000003)
```

### स्पॉट बिडिंग रणनीति

```python
from clore_ai import CloreAI

client = CloreAI()

def smart_spot_bid(server_id, premium_pct=5):
    """वर्तमान न्यूनतम स्पॉट कीमत से थोड़ा ऊपर बोली लगाएँ।"""
    offers = client.spot_marketplace(server_id=server_id)
    if not offers:
        print("कोई स्पॉट ऑफ़र नहीं — आधार के रूप में ऑन-डिमांड कीमत उपयोग करें")
        return None

    min_price = min(o["price"] for o in offers)
    bid = min_price * (1 + premium_pct / 100)
    print(f"Market min: {min_price}, bidding: {bid:.8f} (+{premium_pct}%)")
    return bid

# उपयोग
bid = smart_spot_bid(server_id=142, premium_pct=10)
if bid:
    order = client.create_order(
        server_id=142,
        image="cloreai/ubuntu22.04-cuda12",
        type="spot",
        currency="bitcoin",
        spot_price=bid
    )
```

***

## वॉलेट ऑपरेशंस

### बैलेंस चेक करें

```python
wallets = client.wallets()
for w in wallets:
    print(f"{w.name}: {w.balance:.8f}")
    if w.deposit:
        print(f"  Deposit address: {w.deposit}")
```

### कम-बैलेंस अलर्ट

```python
from clore_ai import CloreAI

def check_balance(min_btc=0.001):
    """यदि BTC बैलेंस थ्रेशहोल्ड से कम हो तो अलर्ट।"""
    client = CloreAI()
    wallets = client.wallets()

    for w in wallets:
        if w.name.lower() == "bitcoin" and w.balance < min_btc:
            print(f"⚠️  Low BTC balance: {w.balance:.8f} (minimum: {min_btc})")
            return False

    print("✅ Balances OK")
    return True

check_balance(min_btc=0.001)
```

***

## त्रुटि हैंडलिंग सर्वोत्तम प्रथाएँ

### अपवाद पदानुक्रम

```
CloreAPIError (बेस)
├── DBError           (कोड 1) — डेटाबेस त्रुटि
├── InvalidInputError (कोड 2) — गलत इनपुट
├── AuthError         (कोड 3) — अमान्य API की
├── InvalidEndpointError (कोड 4) — गलत एंडपॉइंट
├── RateLimitError    (कोड 5) — रेट लिमिट (स्वयं-रिकवरी प्रयास)
└── FieldError        (कोड 6) — फ़ील्ड-विशिष्ट त्रुटि
```

### बेसिक त्रुटि हैंडलिंग

```python
from clore_ai import CloreAI
from clore_ai.exceptions import (
    CloreAPIError,
    AuthError,
    RateLimitError,
    InvalidInputError
)

client = CloreAI()

try:
    order = client.create_order(
        server_id=999999,
        image="cloreai/ubuntu22.04-cuda12",
        type="on-demand",
        currency="bitcoin"
    )
except AuthError:
    print("अवैध API की — CLORE_API_KEY की जाँच करें")
except InvalidInputError as e:
    print(f"गलत इनपुट: {e}")
except RateLimitError:
    print("रेट लिमिट — SDK स्वतः पुनः प्रयास करता है, पर अधिकतम पुनः प्रयास पार हो गया")
except CloreAPIError as e:
    print(f"API त्रुटि (कोड {e.code}): {e}")
```

### बैकऑफ के साथ रीट्राई पैटर्न

SDK में रेट लिमिट और नेटवर्क त्रुटियों के लिए इन-बिल्ट रीट्राईज़ हैं (`max_retries=3`). एप्लिकेशन-स्तर रीट्राईज़ के लिए:

```python
import time
from clore_ai import CloreAI
from clore_ai.exceptions import CloreAPIError, RateLimitError

def retry_operation(func, max_attempts=3, base_delay=2.0):
    """एक्सपोनेंशियल बैकऑफ के साथ Clore API ऑपरेशन को रिट्राई करें।"""
    for attempt in range(max_attempts):
        try:
            return func()
        except RateLimitError:
            if attempt < max_attempts - 1:
                delay = base_delay * (2 ** attempt)
                print(f"Rate limited, retrying in {delay}s...")
                time.sleep(delay)
            else:
                raise
        except CloreAPIError as e:
            if e.code in (1,):  # DB त्रुटियाँ अस्थायी हो सकती हैं
                if attempt < max_attempts - 1:
                    time.sleep(base_delay)
                    continue
            raise

# उपयोग
client = CloreAI()
servers = retry_operation(lambda: client.marketplace(gpu="RTX 4090"))
```

***

## प्रदर्शन सुझाव

### 1. क्लाइंट पुन: उपयोग करें

```python
# ❌ खराब — हर बार नया HTTP कनेक्शन बनाता है
for _ in range(10):
    client = CloreAI()
    client.marketplace()
    client.close()

# ✅ अच्छा — HTTP कनेक्शन पुन: उपयोग करता है
client = CloreAI()
for _ in range(10):
    client.marketplace()
client.close()
```

### 2. समवर्ती ऑपरेशन्स के लिए Async का उपयोग करें

```python
import asyncio
from clore_ai import AsyncCloreAI

async def compare_gpus():
    async with AsyncCloreAI() as client:
        # 3 खोजें एक साथ चलाएँ
        rtx4090, rtx3090, a100 = await asyncio.gather(
            client.marketplace(gpu="RTX 4090"),
            client.marketplace(gpu="RTX 3090"),
            client.marketplace(gpu="A100"),
        )

        print(f"RTX 4090: {len(rtx4090)} servers")
        print(f"RTX 3090: {len(rtx3090)} servers")
        print(f"A100: {len(a100)} servers")

asyncio.run(compare_gpus())
```

### 3. Async बैच ऑर्डर निर्माण

```python
import asyncio
from clore_ai import AsyncCloreAI

async def batch_deploy(server_ids):
    async with AsyncCloreAI() as client:
        tasks = [
            client.create_order(
                server_id=sid,
                image="cloreai/ubuntu22.04-cuda12",
                type="on-demand",
                currency="bitcoin",
                ssh_password="BatchPass123",
                ports={"22": "tcp"}
            )
            for sid in server_ids
        ]
        orders = await asyncio.gather(*tasks, return_exceptions=True)

        for sid, result in zip(server_ids, orders):
            if isinstance(result, Exception):
                print(f"Server {sid}: FAILED — {result}")
            else:
                print(f"Server {sid}: Order {result.id} created")

        return orders

# एक साथ 3 सर्वरों पर डिप्लॉय करें
asyncio.run(batch_deploy([142, 305, 891]))
```

{% hint style="warning" %}
**नोट:** SDK कॉल्स के बीच 5-सेकंड कूलडाउन लागू करता है। `create_order` यहाँ तक कि async मोड में भी, ऑर्डर रेट लिमिट का सम्मान करने के लिए अंतराल पर रखें जाते हैं।
{% endhint %}

### 4. काम पूरा होने पर क्लाइंट बंद करें

```python
# कंटेक्स्ट मैनेजर यह स्वतः संभालता है
with CloreAI() as client:
    # काम...
    pass  # client.close() स्वतः कॉल किया जाता है

# या मैन्युअल रूप से बंद करें
client = CloreAI()
try:
    # काम...
    pass
finally:
    client.close()
```

***

## पूर्ण उदाहरण: ऑटो-स्केल GPU वाकर

```python
import asyncio
import time
from clore_ai import AsyncCloreAI
from clore_ai.exceptions import CloreAPIError

async def auto_scale(
    gpu_model="RTX 4090",
    max_price=2.0,
    target_workers=3,
    image="cloreai/ubuntu22.04-cuda12"
):
    """GPU वर्करों का पूल बनाए रखें।"""
    async with AsyncCloreAI() as client:
        # 1. वर्तमान ऑर्डर्स जांचें
        current_orders = await client.my_orders()
        active_count = len(current_orders)
        print(f"Active workers: {active_count}/{target_workers}")

        if active_count >= target_workers:
            print("पहले से ही लक्ष्य पर हैं। कुछ करने की आवश्यकता नहीं।")
            return

        # 2. उपलब्ध सर्वर ढूंढें
        servers = await client.marketplace(gpu=gpu_model, max_price_usd=max_price)
        servers.sort(key=lambda s: s.price_usd or float("inf"))

        needed = target_workers - active_count
        candidates = servers[:needed]

        if len(candidates) < needed:
            print(f"Only {len(candidates)} servers available (need {needed})")

        # 3. Deploy
        for server in candidates:
            try:
                order = await client.create_order(
                    server_id=server.id,
                    image=image,
                    type="on-demand",
                    currency="bitcoin",
                    ssh_password="WorkerPass123",
                    ports={"22": "tcp"}
                )
                print(f"Deployed on server {server.id} → order {order.id}")
            except CloreAPIError as e:
                print(f"Failed to deploy on {server.id}: {e}")

asyncio.run(auto_scale())
```

***

## अगले चरण

* [CLI स्वचालन](https://docs.clore.ai/guides/guides_v2-hi/advanced/cli-automation) — बैश स्क्रिप्ट्स, CI/CD, बैच ऑपरेशंस
* [बैच प्रोसेसिंग](https://docs.clore.ai/guides/guides_v2-hi/advanced/batch-processing) — Clore GPU पर बड़े वर्कलोड्स प्रोसेस करें
* [API एकीकरण](https://docs.clore.ai/guides/guides_v2-hi/advanced/api-integration) — अपने ऐप्स से AI सेवाओं को कनेक्ट करें
