> 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/clore.ai/clore.ai-eng-zh/kai-fa-zhe/python-sdk.md).

# Python SDK（clore-ai）

该 **clore-ai** 软件包是用于以下内容的官方 Python SDK： [Clore.ai](https://clore.ai) GPU 市场。它将整个 REST API 封装为一个简洁、类型安全的接口，并内置速率限制、自动重试和结构化错误处理——让你可以专注于租用 GPU，而不是处理 HTTP 细节。

***

## 安装

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

**需求：** Python 3.9+

该软件包同时安装 Python SDK 和 [`clore` CLI](/clore.ai/clore.ai-eng-zh/kai-fa-zhe/cli-guide.md).

***

## 身份验证

从以下位置获取你的 API 密钥： [Clore.ai 控制台](https://clore.ai) → **API** 部分。

### 选项 1：环境变量（推荐）

```bash
export CLORE_API_KEY=your_api_key_here
```

SDK 会自动读取 `CLORE_API_KEY` 自动读取——无需修改代码。

### 选项 2：CLI 配置文件

```bash
clore config set api_key YOUR_API_KEY
```

这会将密钥存储在 `~/.clore/config.json`.

### 选项 3：在代码中直接传入

```python
from clore_ai import CloreAI

client = CloreAI(api_key="your_api_key_here")
```

> ⚠️ **重要：** Clore.ai API 使用 `auth` header 进行身份验证， **不是** `Authorization: Bearer`。SDK 会自动处理。

***

## 快速开始

```python
from clore_ai import CloreAI

client = CloreAI()
servers = client.marketplace(gpu="RTX 4090", max_price_usd=5.0)
for s in servers:
    print(f"服务器 {s.id}: {s.gpu_model} — ${s.price_usd:.4f}/h")
```

***

## 同步客户端（`CloreAI`)

### 构造函数

```python
CloreAI(
    api_key: str | None = None,       # 回退到 CLORE_API_KEY 环境变量 / 配置
    base_url: str | None = None,       # 默认：https://api.clore.ai/v1
    timeout: float = 30.0,             # 请求超时时间（秒）
    max_retries: int = 3               # 速率限制 / 网络错误时的重试次数
)
```

该客户端支持上下文管理器以便自动清理：

```python
with CloreAI() as client:
    wallets = client.wallets()
    # 自动调用 client.close()
```

***

### `wallets()`

获取你的钱包余额和充值地址。

```python
wallets = client.wallets()

for wallet in wallets:
    print(f"{wallet.name}: {wallet.balance:.8f}")
    if wallet.deposit:
        print(f"  充值地址：{wallet.deposit}")
```

**返回值：** `List[Wallet]`

| 字段               | 类型              | 描述                                                             |
| ---------------- | --------------- | -------------------------------------------------------------- |
| `name`           | `str`           | 货币名称（例如 `"bitcoin"`, `"CLORE-Blockchain"`, `"USD-Blockchain"`) |
| `balance`        | `float \| None` | 当前余额                                                           |
| `deposit`        | `str \| None`   | 充值地址                                                           |
| `withdrawal_fee` | `float \| None` | 提现手续费                                                          |

***

### `marketplace()`

使用可选的客户端过滤条件搜索 GPU 市场。

```python
# 所有可用服务器
servers = client.marketplace()

# 按 GPU 型号和最高价格过滤
servers = client.marketplace(
    gpu="RTX 4090",
    max_price_usd=5.0
)

# 具有充足 RAM 的多 GPU 机器
servers = client.marketplace(
    min_gpu_count=4,
    min_ram_gb=128.0
)
```

**参数：**

| 参数               | 类型              | 默认值    | 描述                      |
| ---------------- | --------------- | ------ | ----------------------- |
| `gpu`            | `str \| None`   | `None` | 按 GPU 型号过滤（不区分大小写的子串匹配） |
| `min_gpu_count`  | `int \| None`   | `None` | GPU 最少数量                |
| `min_ram_gb`     | `float \| None` | `None` | 最小 RAM（GB）              |
| `max_price_usd`  | `float \| None` | `None` | 每小时最高价格（USD）            |
| `available_only` | `bool`          | `True` | 仅返回可租用的服务器              |

**返回值：** `List[MarketplaceServer]`

每个 `MarketplaceServer` 都提供了便捷属性以访问最常用字段，并可访问完整的嵌套数据：

| 属性               | 类型              | 描述                                          |
| ---------------- | --------------- | ------------------------------------------- |
| `id`             | `int`           | 服务器唯一 ID                                    |
| `gpu_model`      | `str \| None`   | 主 GPU 描述（例如 `"1x NVIDIA GeForce RTX 4090"`) |
| `gpu_count`      | `int`           | GPU 数量（来自 `gpu_array`)                      |
| `ram_gb`         | `float \| None` | RAM（GB）                                     |
| `price_usd`      | `float \| None` | 按需价格（USD）                                   |
| `spot_price_usd` | `float \| None` | 现货价格（USD）                                   |
| `available`      | `bool`          | 服务器是否可用（未出租）                                |
| `location`       | `str \| None`   | 来自网络规格的国家代码                                 |

对于高级用例，你可以访问完整的嵌套结构：

| 字段            | 类型                     | 描述                                                                          |
| ------------- | ---------------------- | --------------------------------------------------------------------------- |
| `specs`       | `ServerSpecs \| None`  | 完整硬件规格（`specs.gpu`, `specs.ram`, `specs.cpu`, `specs.disk`, `specs.net`，等等） |
| `price`       | `ServerPrice \| None`  | 完整价格对象（`price.usd.on_demand_usd`, `price.usd.spot`, `price.on_demand`，等等）   |
| `rented`      | `bool \| None`         | 服务器当前是否已出租                                                                  |
| `reliability` | `float \| None`        | 服务器可靠性评分                                                                    |
| `rating`      | `ServerRating \| None` | 服务器评分（`rating.avg`, `rating.cnt`)                                           |

> **注意：** 该 `marketplace()` 该端点是公开的——无需 API 密钥即可使用。

***

### `my_servers()`

列出你提供到 Clore.ai 市场的服务器。

```python
my_servers = client.my_servers()

for server in my_servers:
    print(f"{server.name}: {server.gpu_model} [{server.status}]")
```

**返回值：** `List[MyServer]`

| 属性           | 类型              | 描述                                                                  |
| ------------ | --------------- | ------------------------------------------------------------------- |
| `id`         | `int`           | 服务器 ID                                                              |
| `name`       | `str \| None`   | 服务器名称                                                               |
| `gpu_model`  | `str \| None`   | 主 GPU 描述                                                            |
| `ram_gb`     | `float \| None` | RAM（GB）                                                             |
| `status`     | `str`           | 人类可读状态： `"Online"`, `"Offline"`, `"Disconnected"`，或 `"Not Working"` |
| `已连接`        | `bool \| None`  | 服务器是否已连接                                                            |
| `在线`         | `bool \| None`  | 服务器是否在线                                                             |
| `visibility` | `str \| None`   | `"public"` 或 `"private"`                                            |

***

### `server_config(server_name)`

获取你托管的特定服务器配置。

```python
config = client.server_config("MyGPU")

print(f"服务器：{config.name}")
print(f"GPU：{config.gpu_model}")
print(f"最短租期：{config.mrl}h")
print(f"按需：${config.on_demand_price}")
print(f"现货：${config.spot_price}")
```

**参数：**

| 参数            | 类型    | 描述    |
| ------------- | ----- | ----- |
| `server_name` | `str` | 服务器名称 |

**返回值：** `ServerConfig`

| 属性                | 类型                    | 描述                       |
| ----------------- | --------------------- | ------------------------ |
| `name`            | `str \| None`         | 服务器名称                    |
| `gpu_model`       | `str \| None`         | 主 GPU 描述                 |
| `mrl`             | `int \| None`         | 最大租用时长（小时）               |
| `on_demand_price` | `float \| None`       | 首个可用的按需 USD 价格           |
| `spot_price`      | `float \| None`       | 首个可用的现货 USD 价格           |
| `specs`           | `ServerSpecs \| None` | 完整硬件规格                   |
| `已连接`             | `bool \| None`        | 服务器是否已连接                 |
| `visibility`      | `str \| None`         | `"public"` 或 `"private"` |

***

### `my_orders(include_completed)`

获取你当前的订单，可选包含已完成/已过期订单。

```python
# 仅活跃订单
orders = client.my_orders()

# 包含已完成订单
all_orders = client.my_orders(include_completed=True)

for order in orders:
    print(f"订单 {order.id}: {order.type} — {order.status}")
    if order.pub_cluster:
        print(f"  IP：{order.pub_cluster}")
    if order.tcp_ports:
        print(f"  端口：{order.tcp_ports}")
```

**参数：**

| 参数                  | 类型     | 默认值     | 描述          |
| ------------------- | ------ | ------- | ----------- |
| `include_completed` | `bool` | `False` | 包含已完成/已过期订单 |

**返回值：** `List[Order]`

| 字段            | 类型              | 描述                       |
| ------------- | --------------- | ------------------------ |
| `id`          | `int`           | 订单唯一 ID                  |
| `server_id`   | `int \| None`   | 服务器 ID                   |
| `type`        | `str`           | `"on-demand"` 或 `"spot"` |
| `status`      | `str \| None`   | 订单状态                     |
| `image`       | `str \| None`   | Docker 镜像                |
| `currency`    | `str \| None`   | 支付货币                     |
| `price`       | `float \| None` | 每日订单价格                   |
| `pub_cluster` | `str \| None`   | 用于访问的公网主机名/IP            |
| `tcp_ports`   | `dict \| None`  | TCP 端口映射                 |

***

### `spot_marketplace(server_id)`

查看特定服务器的现货市场报价。

```python
spot = client.spot_marketplace(server_id=6)

if spot.offers:
    for offer in spot.offers:
        print(f"订单 {offer.order_id}: ${offer.price}/day（服务器 {offer.server_id}）")

if spot.currency_rates_in_usd:
    for coin, rate in spot.currency_rates_in_usd.items():
        print(f"  {coin}：${rate}")
```

**参数：**

| 参数          | 类型    | 描述         |
| ----------- | ----- | ---------- |
| `server_id` | `int` | 要检查的服务器 ID |

**返回值：** `SpotMarket`

| 字段                      | 类型                         | 描述                                       |
| ----------------------- | -------------------------- | ---------------------------------------- |
| `报价`                    | `List[SpotOffer] \| None`  | 现货报价列表（`order_id`, `price`, `server_id`) |
| `server`                | `SpotServerInfo \| None`   | 服务器信息（最低价格、可见性、在线状态）                     |
| `currency_rates_in_usd` | `Dict[str, float] \| None` | 以 USD 表示的货币汇率                            |

***

### `create_order(...)`

创建新的按需或现货订单。这就是租用 GPU 的方式。

#### 按需订单

```python
order = client.create_order(
    server_id=123,
    image="cloreai/ubuntu22.04-cuda12",
    type="on-demand",
    currency="bitcoin",
    ssh_password="MySecurePass123",
    ports={"22": "tcp", "8888": "http"}
)

print(f"订单已创建：{order.id}")
print(f"连接：{order.pub_cluster}")
```

#### 现货订单

```python
order = client.create_order(
    server_id=123,
    image="cloreai/pytorch",
    type="spot",
    currency="bitcoin",
    spot_price=0.000005,
    ssh_password="MySecurePass123",
    ports={"22": "tcp"}
)
```

**参数：**

| 参数                   | 类型          | 必填   | 描述                                                                                                                     |
| -------------------- | ----------- | ---- | ---------------------------------------------------------------------------------------------------------------------- |
| `server_id`          | `int`       | 是    | 要租用的服务器 ID                                                                                                             |
| `image`              | `str`       | 是    | Docker 镜像（例如 `"cloreai/ubuntu22.04-cuda12"`)                                                                           |
| `type`               | `str`       | 是    | `"on-demand"` 或 `"spot"`                                                                                               |
| `currency`           | `str`       | 是    | 支付货币（例如 `"bitcoin"`)                                                                                                   |
| `ssh_password`       | `str`       | 否    | SSH 密码（字母数字，最多 32 个字符）                                                                                                 |
| `ssh_key`            | `str`       | 否    | SSH 公钥（最多 3072 个字符）                                                                                                    |
| `ports`              | `dict`      | 否    | 端口映射，例如 `{"22": "tcp", "8888": "http"}`                                                                                |
| `env`                | `dict`      | 否    | 环境变量                                                                                                                   |
| `jupyter_token`      | `str`       | 否    | Jupyter notebook 令牌（最多 32 个字符）                                                                                         |
| `command`            | `str`       | 否    | 容器启动后运行的 Shell 命令                                                                                                      |
| `spot_price`         | `float`     | 仅限现货 | 现货订单的每日价格                                                                                                              |
| `required_price`     | `float`     | 否    | 锁定特定价格（仅适用于按需）                                                                                                         |
| `autossh_entrypoint` | `str`       | 否    | 使用 Clore.ai SSH 入口点                                                                                                    |
| `gpu_count`          | `int`       | 否    | 仅在具有以下条件的服务器上租用 N 个 GPU [部分租用](/clore.ai/clore.ai-eng-zh/mian-xiang-zu-yong-zhe/partial-gpu-rental.md) （仅按需）；省略则租用整台设备 |
| `gpu_indices`        | `list[int]` | 否    | 来自以下的精确 GPU 插槽 `partial_gpu_rental.free_indices`；长度必须等于 `gpu_count`；省略则自动选择                                            |

**返回值：** 原始 API 响应（`{"code": 0}` 成功时）；可通过以下方式获取已创建的订单： `my_orders()`

> **速率限制：** `create_order` 在调用之间有一个特殊的 5 秒冷却时间。SDK 会自动强制执行。

***

### `cancel_order(order_id, issue)`

取消一个活动订单或现货报价。可选地向服务器报告问题。

```python
# 简单取消
client.cancel_order(order_id=38)

# 带问题报告的取消
client.cancel_order(
    order_id=38,
    issue="GPU #1 过热并出现降频"
)
```

**参数：**

| 参数         | 类型    | 必填 | 描述                       |
| ---------- | ----- | -- | ------------------------ |
| `order_id` | `int` | 是  | 要取消的订单 ID                |
| `issue`    | `str` | 否  | 取消原因 / 问题报告（最多 2048 个字符） |

**返回值：** `Dict[str, Any]`

***

### `set_server_settings(...)`

更新你在市场上托管的服务器设置。

```python
client.set_server_settings(
    name="MyGPU",
    availability=True,
    mrl=96,
    on_demand=0.0001,
    spot=0.00000113
)
```

**参数：**

| 参数             | 类型      | 必填 | 描述         |
| -------------- | ------- | -- | ---------- |
| `name`         | `str`   | 是  | 服务器名称      |
| `availability` | `bool`  | 否  | 服务器是否可被租用  |
| `mrl`          | `int`   | 否  | 最大租用时长（小时） |
| `on_demand`    | `float` | 否  | 按需每日价格     |
| `spot`         | `float` | 否  | 每日最低现货价格   |

**返回值：** `Dict[str, Any]`

***

### `set_spot_price(order_id, price)`

更新你在现货市场上的报价价格。

```python
client.set_spot_price(order_id=39, price=0.000003)
```

**参数：**

| 参数         | 类型      | 描述         |
| ---------- | ------- | ---------- |
| `order_id` | `int`   | 现货订单/报价 ID |
| `price`    | `float` | 新的每日价格     |

**返回值：** `Dict[str, Any]`

> **注意：** 你每 600 秒只能降低一次现货价格，而且只能按有限的步长调整。如果你超过这些限制，API 会返回 `code: 6` 并附带详细信息。

***

## 异步客户端（`AsyncCloreAI`)

该 `AsyncCloreAI` 客户端提供与 `CloreAI`相同的方法，但所有方法都返回协程。当你需要并发 API 调用或在异步应用中工作时使用它。

### 基本用法

```python
import asyncio
from clore_ai import AsyncCloreAI

async def main():
    async with AsyncCloreAI(api_key="your_key") as client:
        wallets = await client.wallets()
        for w in wallets:
            print(f"{w.name}: {w.balance:.8f}")

asyncio.run(main())
```

### 并发操作

使用 `asyncio.gather`:

```python
import asyncio
from clore_ai import AsyncCloreAI

async def compare_gpus():
    async with AsyncCloreAI() as client:
        # 并发搜索多个 GPU 型号
        rtx4090, rtx3090, a100 = await asyncio.gather(
            client.marketplace(gpu="RTX 4090"),
            client.marketplace(gpu="RTX 3090"),
            client.marketplace(gpu="A100"),
        )

        for name, servers in [("RTX 4090", rtx4090), ("RTX 3090", rtx3090), ("A100", a100)]:
            if servers:
                cheapest = min(s.price_usd or float('inf') for s in servers)
                print(f"{name}: {len(servers)} 个可用，最低 ${cheapest:.4f}/小时")
            else:
                print(f"{name}: 无可用")

asyncio.run(compare_gpus())
```

### 可用方法

`AsyncCloreAI` 支持与 `CloreAI`:

| 方法                                  | 描述        |
| ----------------------------------- | --------- |
| `await wallets()`                   | 获取钱包余额    |
| `await marketplace(...)`            | 搜索市场      |
| `await my_servers()`                | 列出你托管的服务器 |
| `await server_config(name)`         | 获取服务器配置   |
| `await my_orders(...)`              | 列出你的订单    |
| `await spot_marketplace(server_id)` | 获取现货市场报价  |
| `await create_order(...)`           | 创建新订单     |
| `await cancel_order(...)`           | 取消订单      |
| `await set_server_settings(...)`    | 更新服务器设置   |
| `await set_spot_price(...)`         | 更新现货价格    |

***

## 错误处理

SDK 为每个 API 错误代码都提供了结构化异常类。

```python
from clore_ai import CloreAI
from clore_ai.exceptions import (
    CloreAPIError,      # 所有 API 错误的基类
    AuthError,          # 代码 3 — 无效的 API 密钥
    RateLimitError,     # 代码 5 — 超出速率限制
    InvalidInputError,  # 代码 2 — 错误的请求数据
    DBError,            # 代码 1 — 数据库错误
    InvalidEndpointError,  # 代码 4 — 无效端点
    FieldError,         # 代码 6 — 特定字段错误
)

client = CloreAI()

try:
    order = client.create_order(
        server_id=123,
        image="cloreai/ubuntu22.04-cuda12",
        type="on-demand",
        currency="bitcoin",
    )
except AuthError:
    print("无效的 API 密钥。请检查你的 CLORE_API_KEY。")
except RateLimitError:
    print("已触发速率限制。SDK 会自动重试，但你已达到最大重试次数。")
except InvalidInputError as e:
    print(f"错误的请求：{e}")
except FieldError as e:
    # 代码 6 错误会在响应中包含详细信息
    print(f"字段错误：{e}（详细信息：{e.response}）")
except CloreAPIError as e:
    print(f"API 错误：{e}（代码：{e.code}）")
```

### 错误代码

| 代码 | 异常                     | 描述                           |
| -- | ---------------------- | ---------------------------- |
| 0  | —                      | 成功                           |
| 1  | `DBError`              | 数据库错误                        |
| 2  | `InvalidInputError`    | 无效输入数据                       |
| 3  | `AuthError`            | 无效的 API 令牌                   |
| 4  | `InvalidEndpointError` | 无效端点                         |
| 5  | `RateLimitError`       | 超出速率限制                       |
| 6  | `FieldError`           | 特定字段中的错误（请参见 `error` 响应中的字段） |

所有异常类都继承自 `CloreAPIError` 并包含：

* `e.code` — 数字错误代码
* `e.response` — 完整的 API 响应字典（如可用）

***

## 速率限制

SDK 包含内置速率限制器，会自动强制执行 Clore.ai 的限制：

| 端点             | 限制            |
| -------------- | ------------- |
| 大多数端点          | **1 次请求/秒**   |
| `create_order` | **1 次请求/5 秒** |

当 API 返回速率限制错误（代码 5）时，SDK 会应用 **指数退避** 并最多重试 `max_retries` 次（默认：3）。你无需添加 `time.sleep()` 在调用之间。

### 工作原理

1. 在每次请求之前，速率限制器会等待直到最小间隔已过去。
2. `create_order` 调用会额外强制执行 5 秒冷却时间。
3. 在速率限制错误时，SDK 会指数退避：1 秒 → 2 秒 → 4 秒 → ...
4. 在 `max_retries` 失败尝试后，会抛出一个 `RateLimitError` 异常。

### 自定义重试行为

```python
client = CloreAI(
    max_retries=5,    # 为长时间运行的脚本增加更多重试次数
    timeout=60.0      # 为较慢的连接设置更长的超时时间
)
```

***

## 配置

### 配置文件

CLI 会将配置存储在 `~/.clore/config.json`:

```json
{
  "api_key": "your_api_key_here"
}
```

### 解析顺序

SDK 按以下顺序解析 API 密钥：

1. `api_key` 传递给构造函数的参数
2. `CLORE_API_KEY` 环境变量
3. `api_key` 中的字段 `~/.clore/config.json`

### 环境变量

| 变量              | 描述             |
| --------------- | -------------- |
| `CLORE_API_KEY` | 用于身份验证的 API 密钥 |

***

## 下一步

* [**CLI 参考**](/clore.ai/clore.ai-eng-zh/kai-fa-zhe/cli-guide.md) — 在终端中使用 Clore.ai
* [**REST API**](/clore.ai/clore.ai-eng-zh/mian-xiang-zhu-ji-ti-gong-zhe/api.md) — 用于自定义集成的原始 API 文档
* [**按需与现货**](/clore.ai/clore.ai-eng-zh/mian-xiang-zu-yong-zhe/on-demand-vs-spot.md) — 了解定价模式
* [**可用的 Docker 镜像**](/clore.ai/clore.ai-eng-zh/mian-xiang-zu-yong-zhe/docker-images.md) — 用于 GPU 工作负载的预构建镜像


---

# 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/clore.ai/clore.ai-eng-zh/kai-fa-zhe/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.
