Metadata-Version: 2.4
Name: huace-aigc-maas-client
Version: 0.1.1
Summary: Python client for the new-api MaaS managed-key API
Requires-Python: >=3.10
Description-Content-Type: text/markdown

# Huace AIGC MaaS Python SDK

这是用于接入 new-api MaaS 托管 Key 能力的 Python 客户端。它负责申请或复用托管 Key、查询
Key 元信息和查询用量，不是 AIGC Auth SDK，也不代替模型协议客户端。

SDK 仅依赖 Python 标准库，支持 Python 3.10 及更高版本。

## 安装

```bash
pip install huace-aigc-maas-client
```

## 使用前准备

调用 SDK 前，请确认服务端已经完成以下配置：

- `base_url` 是 MaaS/new-api 服务地址，并使用 HTTPS。
- `app_id` 是已注册的正整数 AIGC Auth 应用 ID。
- 应用已启用，并且恰好配置一个启用的 MaaS 路由。
- 当前用户与服务端人员的映射已经确认，否则会返回 `MAPPING_REVIEW_PENDING`。
- 申请托管 Key 时不需要传 `channel_code` 或来源应用 Secret。

## 快速开始

`ensure_key` 使用当前用户从 AIGC Auth 获取的用户 Token，申请或复用一个托管 Key：

```python
from huace_aigc_maas import APIError, Client, EnsureKeyRequest, UsageQuery

client = Client("https://maas.example.com", "12")

try:
    ensured = client.ensure_key(
        EnsureKeyRequest(
            user_token="auth-user-token",
            idempotency_key="user-42-provision-v1",
        )
    )

    # 托管 Key 只在服务端使用，请勿写入日志或返回浏览器。
    api_key = ensured.credential.api_key
    base_url = ensured.credential.base_url
    models = ensured.credential.models

    key_info = client.get_key_info(api_key)
    usage = client.get_usage(api_key, UsageQuery())
except APIError as exc:
    print(exc.status_code, exc.code, exc.message)
    raise
```

`ensure_key` 返回 `EnsureKeyResult`，其中包括：

- `state`：本次申请或复用的状态。
- `app`：应用信息，包括 `id` 和 `name`。
- `user`：用户映射信息，包括本地用户 ID 和 AIGC Auth 用户 ID。
- `credential`：托管凭证，包括 `api_key`、`base_url` 和可用 `models`。

同一个应用和用户会复用同一个托管 Key。未传 `idempotency_key` 时，SDK 会自动生成 UUID，
并在重试请求中复用该值。

模型请求由调用方使用返回的 `base_url` 和 `api_key` 完成。例如，模型接口地址通常为
`{base_url}/v1/chat/completions`，请求头使用 `Authorization: Bearer <api_key>`。

## 查询 Key 和用量

### 查询 Key 信息

```python
key_info = client.get_key_info(api_key)
print(key_info.status, key_info.models, key_info.remain_quota)
```

`get_key_info` 返回 Key 状态、所属应用和用户、可用模型、额度等信息，不会返回明文 Key。

### 查询用量

不传时间范围时，查询服务端默认统计范围：

```python
usage = client.get_usage(api_key)
print(usage.summary.count, usage.summary.token_used)
```

也可以使用 Unix 时间戳限定查询范围：

```python
usage = client.get_usage(
    api_key,
    UsageQuery(start_timestamp=1722470400, end_timestamp=1725148800),
)

for model in usage.models:
    print(model.model_name, model.count, model.token_used)
```

## 接口和鉴权

| 方法 | 路径 | Authorization 使用的凭证 | 说明 |
| --- | --- | --- | --- |
| `POST` | `/api/integrations/v1/keys/ensure` | AIGC Auth 用户 Token | 申请或复用托管 Key |
| `GET` | `/api/integrations/v1/self/key` | MaaS API Key | 查询 Key 信息 |
| `GET` | `/api/integrations/v1/self/usage` | MaaS API Key | 查询用量 |

申请接口还会发送以下请求头：

- `X-AIGC-Auth-App-Id: <app_id>`
- `Idempotency-Key: <stable value>`

SDK 会自动添加 `Authorization: Bearer ...`。如果传入的凭证已经带有 `Bearer` 前缀，SDK
会规范化后再发送。

## 超时、重试和错误处理

```python
client = Client(
    "https://maas.example.com",
    "12",
    timeout=10.0,
    max_retries=2,
    retry_base_delay=0.1,
)
```

- 默认请求超时为 10 秒。
- 默认最多重试 2 次，采用指数退避。
- 网络错误、HTTP 429 和 HTTP 5xx 会自动重试。
- 其他 HTTP 4xx 错误不会自动重试。
- 服务端错误会抛出 `APIError`，可读取 `status_code`、`code` 和 `message`。

参数格式错误（例如 `base_url` 缺少协议或 `app_id` 不是正整数）会直接抛出 `ValueError`。

## 安全边界

- `user_token` 只传给 `ensure_key`，`Client` 不会保存它。
- 托管 API Key 只能在受信任的服务端保存和使用，不要让浏览器直接持有。
- 所有请求都应通过 HTTPS 传输。
- 不要把用户 Token、托管 API Key 写入日志、URL、指标或错误上报。
- 不要向申请接口传来源应用 Secret。

## 相关文档

- [调用规范（SKILL.md）](SKILL.md)：供 Agent 和服务端集成时参考。
- [MaaS OpenAPI 契约](../openapi/maas.yaml)：查看完整 HTTP 请求和响应定义。

## 本地测试

在 SDK 源码目录执行：

```bash
python -m unittest discover -s tests -v
```
