Metadata-Version: 2.4
Name: spinestudio-sdk
Version: 0.1.0
Summary: spinestudio 官方 Python 客户端 SDK：聊天（同步 + SSE 流式）/ KB / 会话 / 触发器
License-Expression: MIT
License-File: LICENSE
Requires-Python: >=3.10
Provides-Extra: dev
Requires-Dist: pytest>=8.0.0; extra == 'dev'
Requires-Dist: ruff>=0.6; extra == 'dev'
Description-Content-Type: text/markdown

# spinestudio-sdk

spinestudio 官方 Python 客户端。零第三方依赖（stdlib urllib），可独立 `pip install`。

```bash
pip install spinestudio-sdk
```

## 用法

```python
from spinestudio_sdk import SpinestudioClient

client = SpinestudioClient("https://api.example.com", "sk-...")

# 同步聊天（消费整条 SSE 流并聚合）
result = client.chat("<workspace_id>", "本季度营收多少？")
print(result.answer)
for s in result.sources:          # 反捏造溯源如实透传；查无实据则 sources 为空
    print(s["doc"], s.get("locator"))

# 流式聊天（按序拿 token → sources → done 事件）
for event in client.stream_chat("<workspace_id>", "本季度营收多少？"):
    if event.type == "token":
        print(event.data["text"], end="", flush=True)

# 知识库文档
client.list_documents("<workspace_id>")
client.create_document("<workspace_id>", "标题", [{
    "metric": "REVENUE", "entity": "ACME_CN", "period_type": "FY",
    "period": "2024", "value": 1320, "unit": "USD_M",
}])
client.get_document("<workspace_id>", "<doc_id>")
client.delete_document("<workspace_id>", "<doc_id>")

# 会话
client.list_conversations("<workspace_id>")
client.get_conversation("<workspace_id>", "<conversation_id>")

# 触发器
client.fire_trigger("<workspace_id>", "<trigger_id>")
client.webhook_trigger("<workspace_id>", "<trigger_id>", payload={"event": "push"})
```

## 凭据说明

`api_key` 是任意 Bearer 凭据：

- **Service API-Key（`sk-…`）**——workspace 作用域、`read` / `write` 两档 scope，至多等价 member；
  适合程序化聊天 / KB 读 / 触发器 webhook（需 `write`）。
- **用户 JWT**——会话「列表 / 新建 / 删除」是用户作用域端点，需用户 JWT（服务 key 会得 401）。

## 错误语义

非 2xx 抛异常，携带 `.status` 与 `.message`：`AuthenticationError`(401) / `PermissionDeniedError`(403) /
`NotFoundError`(404) / `APIError`(其它)，均继承 `SpinestudioError`。

## 开发

```bash
cd sdks/python
uv venv .venv
VIRTUAL_ENV="$(pwd)/.venv" uv pip install -e ".[dev]"
.venv/bin/python -m pytest -q     # 全离线，注入假传输，绝不触网
```
