Metadata-Version: 2.5
Name: wx_ai_proxy_client
Version: 0.1.0
Summary: Lightweight sync/async Python SDK for the AI API Proxy HTTP service (chat / images / videos).
Keywords: ai,httpx,image-generation,proxy,sdk,video-generation
Classifier: Framework :: AsyncIO
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Typing :: Typed
Requires-Python: >=3.8
Requires-Dist: httpx>=0.23
Provides-Extra: stream
Requires-Dist: httpx-sse>=0.4; extra == 'stream'
Description-Content-Type: text/markdown

# AI Proxy Python SDK（同步/异步）

独立的轻量 SDK，便于在 Python 中调用本服务的 HTTP API（`chat` / `images` / `videos` / `nano_banana`），无需依赖 `ai_api_proxy` 服务端代码。基于 [`httpx`](https://www.python-httpx.org/) 实现，同时提供同步与异步客户端。

## 安装

```bash
pip install wx_ai_proxy_client
```

> 流式接口（`generate_image_stream`，SSE）需要额外依赖 `httpx-sse`，可通过 extra 一并安装：
> ```bash
> pip install "wx_ai_proxy_client[stream]"
> ```
> 它是**可选依赖**，只在调用流式方法时才会被导入；不使用流式功能则无需安装，普通接口仅依赖 `httpx`。

> 说明：PyPI 包名与导入名一致，均为 `wx_ai_proxy_client`（`from wx_ai_proxy_client import ...`）。

## 快速上手

### 同步示例

```python
from wx_ai_proxy_client import (
    AIProxyClient,
    ChatRequest,
    ImageInput,
    ImageGenerateRequest,
    VideoGenerateRequest,
    VideoQueryRequest,
)

client = AIProxyClient(base_url="https://ai-api-proxy.segapi.com", api_key="YOUR_API_KEY")

# Chat（文本/多模态）
chat = client.chat_generate(
    ChatRequest(
        prompt="用一句话介绍一下这张图",
        image_inputs=[ImageInput(image_url="https://example.com/demo.jpg")],
        provider="google",
    )
)
print(chat.text)

# 生成图片
img = client.generate_image(
    ImageGenerateRequest(
        prompt="a cat reading a book",
        system_instruction="keep it cute",
        provider="google",
        model_name="nano-banana",
        response_type="auto",
    )
)
print(img.images[0].image_url if img.images else None)

# Nano Banana：生成 prompt（服务端会返回 `text`，也可能带 `images`）
prompt_result = client.nb_write_prompt(
    ImageGenerateRequest(
        prompt="帮我把这句中文改写成更适合出图的英文提示词：一只戴墨镜的柴犬在海边冲浪",
        provider="google",
    )
)
print(prompt_result.text)

# 生成视频（异步任务）
video_task = client.generate_video(
    VideoGenerateRequest(prompt="a cat jumping on a tree", model_name="sora-2", provider="fal")
)

# 轮询视频结果
result = client.query_video_result(
    VideoQueryRequest(video_id=video_task.video_id, provider=video_task.provider)
)
print(result.status, result.video.video_url if result.video else None)
```

### 异步示例

```python
import asyncio
from wx_ai_proxy_client import AsyncAIProxyClient, ImageGenerateRequest

async def main():
    async with AsyncAIProxyClient(base_url="https://ai-api-proxy.segapi.com", api_key="YOUR_API_KEY") as client:
        data = await client.generate_image(
            ImageGenerateRequest(prompt="a banana spaceship", system_instruction=["high contrast", "studio light"])
        )
        print(data.provider, data.images[0].image_url[:50] if data.images else None)

asyncio.run(main())
```

## 路由与参数

- 所有请求自动带上 `Content-Type: application/json`，若提供 `api_key` 将附加 `Authorization: Bearer <key>`。
- 可在方法调用时传入 `headers` 覆盖或补充自定义头。

### chat
- `chat_generate(request)` → `POST /api/chat/generate`，返回 `ChatResponse`

`ChatRequest` 字段（SDK 侧为 dataclass，字段名与服务端一致）：

| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `prompt` | `str` | 内容（必填）。 |
| `system_instruction` | `str \| list[str] \| None` | 额外提示。 |
| `provider` | `str` | 供应商，默认 `google`。 |
| `model_name` | `str \| None` | 模型名（可选）。 |
| `image_inputs` | `list[ImageInput] \| None` | 参考图列表（可选）。 |
| `generation_config` | `dict \| None` | 其他配置（可选）。 |

`ChatResponse` 字段：

| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `provider` | `str` | 实际调用的提供方。 |
| `model_name` | `str` | 实际使用的模型名。 |
| `text` | `str \| None` | 返回文本。 |

### images
- `generate_image(request)` → `POST /api/images/generate`，返回 `ImageGenerateResponse`

`ImageGenerateResponse` 字段：

| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `provider` | `str` | 实际调用的提供方。 |
| `images` | `list[ImageResource] \| None` | 生成的图片列表。 |
| `text` | `str \| None` | 生成端返回的附加文本。 |

`ImageResource` 字段：

| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `image_url` | `str` | 图片地址，可能是 URL 或 `data:image/...;base64,...`。 |
| `text` | `str \| None` | 附加描述。 |

`ImageGenerateRequest` 字段：

| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `prompt` | `str` | 描述内容（必填）。 |
| `system_instruction` | `str` 或 `list[str]` | 生成时的附加提示。 |
| `provider` | `str` | 供应商，默认 `google`。 |
| `model_name` | `str \| None` | 模型名（可选），例如 `nano-banana`。 |
| `image_inputs` | `list[ImageInput]` | 参考图，字段 `image_url` 支持 URL 或 `data:<mime>;base64,...`。 |
| `aspect_ratio` | `str` | 目标宽高比，如 `16:9`。 |
| `number` | `int` | 生成数量，默认 `1`。 |
| `response_type` | `str` | `auto` / `url` / `base64`。 |

### nano_banana
- `nb_write_prompt(request)` → `POST /api/nano_banana/write_prompt`，返回 `ImageGenerateResponse`
  - 常用于“先写提示词，再生成图片”的工作流（服务端可能在 `text` 字段返回改写后的提示词）。

### videos
- `generate_video(request)` → `POST /api/videos/generate`，返回 `VideoGenerateResult`
- `query_video_result(request)` → `POST /api/videos/query_result`，返回 `VideoQueryResult`
  - 建议 `provider` 传入与 `generate_video` 返回一致的值（例如 `video_task.provider`），以便路由到正确的后端。

`VideoGenerateResult` 字段：

| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `video_id` | `str` | 任务 ID。 |
| `provider` | `str` | 供应商。 |
| `model_name` | `str` | 使用的模型名。 |
| `status` | `TaskStatus` | 任务状态。 |

`VideoGenerateRequest` 字段：

| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `prompt` | `str` | 描述内容（必填）。 |
| `negative_prompt` | `str \| None` | 负向提示（可选）。 |
| `provider` | `str` | 供应商，默认 `fal`。 |
| `model_name` | `str` | 模型名，默认 `sora-2`。 |
| `system_instruction` | `str` 或 `list[str]` | 额外提示。 |
| `image_inputs` | `list[ImageInput]` | 图生视频的首/尾帧图，`role` 取 `first_frame` / `last_frame`。`role=reference_image` 为老版本参考图写法，仅保留兼容，新版本请改用 `reference_media_inputs`。 |
| `reference_media_inputs` | `list[MediaInput]` | 参考生视频模式的参考素材（图片/视频/音频）。`media_url` 支持 URL 或 `data:<mime>;base64,...`；`category` 取 `image` / `video` / `audio`，不填由服务端按 url 推断。目前 `doubao` / `qcloud`(`minimax-h3-max` 除外) / `minimax` / `kie`(seedance-2 系列、minimax-h3) / `pollo`(seedance-2 系列) / `falai`(seedance-2 系列、minimax-h3 系列) 支持；`falai` 其他模型会忽略参考素材，`openai` 不支持参考模式会报错。 |
| `resolution` | `str` | 目标分辨率，形如 `1280x720`。 |
| `duration` | `float` | 时长（秒），默认 `4`。 |
| `callback_url` | `str` | 可选回调地址。 |

`VideoQueryRequest` 字段：

| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `video_id` | `str` | 生成任务返回的 `video_id`（必填）。 |
| `provider` | `str` | 供应商，默认 `openai`。 |

`VideoQueryResult` 字段：

| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `video_id` | `str` | 任务 ID。 |
| `provider` | `str` | 供应商。 |
| `status` | `TaskStatus` | 任务状态。 |
| `err_msg` | `str \| None` | 失败原因。 |
| `video` | `VideoResource \| None` | 生成结果。 |

`VideoResource` 字段：

| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `video_url` | `str` | 视频地址。 |
| `duration` | `float \| None` | 视频时长。 |
| `resolution` | `str \| None` | 分辨率。 |

## 错误处理

- 所有接口在 HTTP 状态码非 2xx 时抛出 `APIRequestError`，其中包含 `status_code`、`message` 以及原始 `response`。
- SDK 其他异常均继承自 `AIProxySDKError`。

## 高级用法

- 自定义 `timeout`：`AIProxyClient(..., timeout=60)` / `AsyncAIProxyClient(..., timeout=60)`
- 复用自建 `httpx.Client` / `httpx.AsyncClient`：通过构造函数的 `client=` 传入（SDK 会自动识别是否需要自行关闭）。

## 设计说明

- SDK 核心仅依赖 `httpx`（流式方法可选依赖 `httpx-sse`，按需懒加载），不引用 `ai_api_proxy` 内部代码，便于独立分发。
- 同步与异步接口具备一致的方法命名，方便在不同运行环境下切换。
