p0aiapi
P0 API 的 Python SDK,支持 Python 3.10+、同步 / asyncio 调用、任务轮询、音色上传、SSE 和 OpenAPI JSON 动态调用。运行时仅依赖 httpx。
发行包和导入名称均为 p0aiapi,版本 0.1.1。默认 API 地址为 https://p0-api.inaiai.com。
下面的服务接口均见于 YApi 项目 8。包内接口配置结合 YApi 与本地 backend 源码维护;接口是否可用仍取决于实际部署版本。SDK 不会把文档路径自动替换成其他接口。
安装与配置
python -m pip install --upgrade p0aiapi==0.1.1
export P0_API_KEY='你的 API key'
本地开发可使用 python -m pip install -e .。
需要连接其他部署时,设置 P0_API_BASE_URL,或传入 Client(base_url="https://your-api.example.com", api_key="...")。显式参数优先于环境变量,未设置地址时使用 https://p0-api.inaiai.com。地址填写服务根地址;反向代理的路径前缀会被保留。
认证使用 apikey 请求头。api_key= / P0_API_KEY 设置该请求头;可选的 token= / P0_API_TOKEN 额外发送 Authorization: Bearer ...,不替代 apikey。SDK 不内置密钥,初始化不会访问服务器。使用 with 管理连接,或在结束时调用 close()。
后端启用鉴权 v2 时,可设置 P0_API_SECRET_KEY 或传入 Client(api_key="...", secret_key="..."),SDK 会额外发送 X-SECRET-KEY;AsyncClient 用法相同。未设置 secret 时保留原来的 apikey 调用方式。鉴权版本选择与回退由后端处理,是否已启用以实际部署为准。
查询任务
一个 task_id 用 client.tasks.get(),多个 task_id 用 client.tasks.batch()。两种方法直接查询任务状态和结果,不需要加载 OpenAPI 配置。
使用提交任务时返回的 task_id,按原值精确匹配;不能用内部 uuid 或业务 bid 替代,也不要去掉或增加首尾空白。
同步查询
将示例中的任务 ID 替换为已有任务的 task_id:
from p0aiapi import Client
with Client() as client:
task = client.tasks.get("task-1")
print(task.get("status"), task.get("out_data"))
tasks = client.tasks.batch(["task-1", "task-2"])
for task in tasks:
print(task.get("task_id"), task.get("status"), task.get("out_data"))
异步查询
import asyncio
from p0aiapi import AsyncClient
async def main():
async with AsyncClient() as client:
task = await client.tasks.get("task-1")
print(task.get("status"), task.get("out_data"))
tasks = await client.tasks.batch(["task-1", "task-2"])
for task in tasks:
print(task.get("task_id"), task.get("status"), task.get("out_data"))
asyncio.run(main())
异步客户端在同一个 asyncio 事件循环中复用,结束时使用 async with 或 await client.aclose()。
单独查询使用 /api/public/task,成功响应为任务对象;同一 task_id 存在多条记录时,返回记录由服务端决定。
批量查询使用 YApi 3469 的 /api/public/task/details,发送裸 JSON 字符串数组。传入非空 task_id 列表,成功响应直接返回任务对象数组。未命中的 ID 被省略,结果顺序可能与输入不同,同一 ID 可能返回多条记录;请按 task_id 关联结果。
单独查询未命中,或批量查询的所有 ID 均未命中时,SDK 抛出 NotFoundError(HTTP 404)。HTTP 200 表示查询成功,任务是否完成仍需检查 status:2 成功,-1 失败,0 / 1 / 3 继续等待。out_data 保留服务端原始值。
自动等待任务结束
需要自动轮询时使用 wait_for_task()。它轮询单任务查询接口检查状态,直到成功、失败或超时;任务查询可能缓存约 10 秒,建议 poll_interval=10。
from p0aiapi import Client
with Client() as client:
result = client.wait_for_task("task-1", timeout=600, poll_interval=10)
print(result.get("out_data"))
异步用法为 await client.wait_for_task(task_id, timeout=600, poll_interval=10)。超时停止本地等待,后端任务仍继续执行。
常用接口
同步和异步客户端的方法同名;异步请求方法需要 await。
| 方法 | 用途 |
|---|---|
client.images.generate(prompt, **fields) |
文生图 |
client.novels.generate(description, **fields) |
提交小说生成任务 |
client.novels.continue_from(file_url, **fields) |
从公网 TXT / Markdown 文件续写 |
client.audio.list_voices() |
TTS v1 音色列表 |
client.audio.generate(text, **fields) |
TTS v1 语音生成 |
client.audio.upload_voice(spk_id, prompt_text, path) |
上传音色样本及对应文本 |
client.tts.list_speakers() |
TTS v2 音色列表 |
client.tts.generate(text, spk_id, **fields) |
TTS v2 语音生成 |
client.tasks.get(task_id) |
查询任务记录 |
client.tasks.batch([task_id, ...]) |
批量查询任务记录,发送裸 JSON 数组 |
client.tasks.events([task_id, ...]) |
可选的 SSE 任务事件监听 |
client.wait_for_task(task_id, timeout=600) |
本地轮询,等待任务结束 |
生成方法使用后端要求的表单编码。**fields 透传可选参数并省略 None,例如具体接口支持的 task_id、bid、app_id、notify_url。实际字段和默认值以对应接口为准,响应保留原始结构及新增字段。
音色上传使用 multipart,SDK 会关闭自己打开的文件;直接调用 request(files=...) 时由调用方管理文件句柄。
with Client() as client:
voice = client.audio.upload_voice("my-voice", "音频中的原文", "sample.wav")
print(voice)
OpenAPI 接口配置
使用包内配置
load_catalog() 离线加载随包安装的接口配置,使用 yapi_接口ID 作为 operationId。配置只包含本版本支持的 YApi 接口,请求参数按本地 backend 签名校正,不包含文档中的密钥和示例值。
from p0aiapi import Client, load_catalog
with Client(openapi=load_catalog()) as client:
voices = client.call("yapi_2526")
tasks = client.call_endpoint("POST", "/api/public/task/details", json=["task-1", "task-2"])
print(voices, tasks)
p0aiapi operations
p0aiapi export-catalog --output openapi.catalog.json
call_endpoint() 通过方法和路径模板定位已加载的操作。动态调用显式区分 path_params、params(query)、headers、cookies、json、data(form)和 files。表单接口使用 data,不能改用 json。动态调用共用客户端认证、超时和错误处理。
下载部署配置
p0aiapi fetch-schema --output openapi.json
p0aiapi operations openapi.json
CLI 同样使用默认 API 地址和 P0_API_BASE_URL / P0_API_KEY / P0_API_SECRET_KEY / P0_API_TOKEN。文档路径默认 /openapi.json,可通过 --path 指定。下载检查版本和操作目录结构后原子替换文件,失败保留原文件。
from p0aiapi import Client
with Client(openapi="openapi.json") as client:
print(list(client.schema.operations))
也可传入字典或 OpenAPISchema。client.load_openapi("new.json") 从本地更新;client.refresh_openapi() / await client.refresh_openapi() 显式从当前部署下载。加载或刷新会替换当前配置,验证失败时保留原配置;部署文档可能隐藏部分路由,不自动与包内目录合并。
升级前比较
p0aiapi fetch-schema --output openapi.next.json
p0aiapi diff openapi.json openapi.next.json --fail-on-change
输出 added / removed / changed operationId 列表,包含引用模型变化。--fail-on-change 遇到任何差异返回退出码 2,但不自动判定业务兼容性。生产项目建议把快照与代码一起版本控制,测试后升级。
支持 OpenAPI 3.0 / 3.1 JSON、本地 $ref、JSON / URL-encoded / multipart 请求、简单路径参数和普通 query 数组。不支持 YAML、Swagger 2.0 或 deepObject 等复杂序列化;不做完整 JSON Schema 校验,也不生成接口专属类型。便利方法不依赖 OpenAPI 配置,响应不按文档强制转换类型。
request_raw() 返回完整读取的 httpx.Response;request() 根据响应类型返回 JSON、文本、字节或 None。API 请求地址由客户端的 base_url 决定,schema 的 servers 不覆盖它。
可选:SSE 任务事件监听
任务状态和结果推荐通过上面的单独或批量查询获取。需要监听事件时,使用 tasks.events()、stream_events() 或 stream_call() 增量读取。普通 request() / call() 会等待响应结束。流式读取不自动重试或重连,timeout=60 可设置读取空闲超时。
from contextlib import closing
from p0aiapi import Client
with Client() as client:
with closing(client.tasks.events(["task-1", "task-2"], timeout=60)) as events:
for event in events:
print(event.event, event.data)
异步版本返回异步迭代器,创建时不加 await:
from contextlib import aclosing
from p0aiapi import AsyncClient
async def watch():
async with AsyncClient() as client:
async with aclosing(client.tasks.events(["task-1"])) as events:
async for event in events:
print(event.data)
迭代结束、异常或显式 close() / aclose() 会释放连接;提前退出循环时使用上面的上下文管理器。ServerSentEvent 保留原始 data、事件名称、id 和 retry;仅在数据确实为 JSON 时调用 event.json()。服务端事件名称可能与任务终态不同,最终结果使用任务 status 判断或调用 wait_for_task()。
错误、重试和任务状态
from p0aiapi import APIError, Client, TaskFailedError, TaskTimeoutError
with Client() as client:
try:
task = client.audio.generate("你好,世界。")
result = client.wait_for_task(task["task_id"], timeout=600, poll_interval=10)
except APIError as exc:
print(exc.status_code)
if isinstance(exc.body, dict) and exc.body.get("submission_uncertain"):
print("任务可能已入队,请先查询:", exc.body.get("task_id"))
except TaskFailedError as exc:
print(exc.task.get("error"))
except TaskTimeoutError as exc:
print("停止本地等待,后端任务仍在执行", exc.last_task)
- HTTP 错误:
AuthenticationError(401/403)、NotFoundError(404)、ValidationError(422)、RateLimitError(429)、ServerError(5xx)均继承APIError,保留.body、.response、.request_id。默认异常文字不回显凭据或响应内容。 - 连接及 HTTP 超时为
TransportError;坏 JSON、解压失败或不适用的响应为P0ResponseError。这些错误及任务错误继承P0Error。本地配置错误和SchemaError继承ValueError。 - 无请求体的 GET/HEAD/OPTIONS 默认最多重试 2 次,覆盖连接故障和 408/429/500/502/503/504;读取
Retry-After并退避,单次最多等待 30 秒。POST 等写请求不自动重试。若返回submission_uncertain=true,应先查询任务,避免重复提交。 - 状态
0等待、1处理、3水印处理中,继续等待;2成功;-1抛出TaskFailedError,或通过raise_on_failure=False返回失败记录。数字字符串也受支持,未知状态继续等待至超时。 - 轮询在总预算内处理临时连接故障及上述可重试 HTTP 状态;404 和认证错误立即抛出。任务查询可能缓存约 10 秒,建议
poll_interval=10。超时只停止本地等待,不取消远端任务。 - 同步 HTTP 超时按网络阶段计算,正在执行的请求可能超过轮询截止时间;异步等待使用总 deadline,可被调用方取消。
- API 路径必须为
/...;不接受外部 URL,也不自动跟随跳转。下载外部结果请使用独立的 HTTP 客户端。
开发和发布
python -m pip install -e '.[dev]'
pytest
ruff check .
ruff format --check .
python -m build
python -m twine check dist/p0aiapi-0.1.1-py3-none-any.whl dist/p0aiapi-0.1.1.tar.gz
测试使用模拟 HTTP 验证请求、响应、任务状态和错误处理,不提交真实生成任务。离线演示:python examples/offline_demo.py。
发布步骤 · 架构及接口维护。GitHub Actions 包含测试矩阵和手动 TestPyPI / PyPI 发布流程。
Metadata
Release files for p0aiapi 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| p0aiapi-0.1.1.tar.gz | 72.5 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| p0aiapi-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 104.0 kB
Release files / p0aiapi-0.1.1.tar.gz
| Download URL | p0aiapi-0.1.1.tar.gz |
|---|---|
| Size | 72.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9d9f5950cf21d9a85649e64711fd91d0f9858202c63ba45520ff3df080292db4
|
|
BLAKE2b-256 checksum How to use checksums |
f264cca406fd167914f97fbc1d77ba9d5e3e03a39d00e16281cbcdda05ce1ea9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.5
|
Release files / p0aiapi-0.1.1-py3-none-any.whl
| Download URL | p0aiapi-0.1.1-py3-none-any.whl |
|---|---|
| Size | 31.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
036385dce8902e505122267d9e219b5c4ac21e66f8ceacbe39a4a66f91775f0b
|
|
BLAKE2b-256 checksum How to use checksums |
4a447879fc6dc7eeb808c8ce4cd3f29fc4bb33ff389c923aec256bf86a5a8c11
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.5
|
Security for p0aiapi 0.1.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.