> For the complete documentation index, see [llms.txt](https://docs.clore.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.clore.ai/guides/guides_v2-hi/advanced/python-sdk.md).

# Python SDK गाइड

{% hint style="success" %}
**SDK में नया?** शुरू करें [5-मिनट त्वरित आरंभ](/guides/guides_v2-hi/getting-started/python-quickstart.md) पहले।
{% 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 स्वचालन](/guides/guides_v2-hi/advanced/cli-automation.md) — बैश स्क्रिप्ट्स, CI/CD, बैच ऑपरेशंस
* [बैच प्रोसेसिंग](/guides/guides_v2-hi/advanced/batch-processing.md) — Clore GPU पर बड़े वर्कलोड्स प्रोसेस करें
* [API एकीकरण](/guides/guides_v2-hi/advanced/api-integration.md) — अपने ऐप्स से AI सेवाओं को कनेक्ट करें


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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, and the optional `goal` query parameter:

```
GET https://docs.clore.ai/guides/guides_v2-hi/advanced/python-sdk.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
