openai-io
轻量级的 OpenAI 大模型 IO 库:只保留 chat.completions / completions / embeddings
三件套,同步(OpenAI)与异步(AsyncOpenAI)双客户端,传输层基于 httpx,
数据模型基于 pydantic v2。
设计目标:接口与 openai SDK 对齐以降低迁移成本,同时把 message 换成 langchain 风格。
特性
- 🪶 轻量:仅依赖
httpx+pydantic,无其他重量级依赖 - 🔀 同步 / 异步双客户端(
OpenAI/AsyncOpenAI) - 💬 langchain 风格的 message 体系:
SystemMessage/HumanMessage/AIMessage/ToolMessage/FunctionMessage/ChatMessage(自研轻量实现,不依赖 langchain-core) - 🧵 流式输出(SSE):
stream=True返回Stream/AsyncStream迭代器 - 🛡️ 完整类型注解:
pyright --strict0 错误,ruff全绿 - 🔁 自动重试(指数退避 + 抖动)、异常体系与 openai SDK 一致
安装
pip install -e .
要求 Python >= 3.12。
快速开始
同步
from openai_io import OpenAI
from openai_io.messages import HumanMessage, SystemMessage
client = OpenAI() # 或 OpenAI(api_key="sk-...")
resp = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
SystemMessage(content="你是一个友好的助手"),
HumanMessage(content="你好"),
],
)
print(resp.choices[0].message.content)
# embeddings
vectors = client.embeddings.create(model="text-embedding-3-small", input="你好")
print(vectors.data[0].embedding[:5])
# 旧版文本补全
comp = client.completions.create(model="gpt-3.5-turbo-instruct", prompt="1+1=?")
print(comp.choices[0].text)
异步
import asyncio
from openai_io import AsyncOpenAI
from openai_io.messages import HumanMessage
async def main() -> None:
client = AsyncOpenAI()
resp = await client.chat.completions.create(
model="gpt-4o-mini",
messages=[HumanMessage(content="你好")],
)
print(resp.choices[0].message.content)
asyncio.run(main())
流式输出
stream = client.chat.completions.create(
model="gpt-4o-mini",
messages=[HumanMessage(content="讲个故事")],
stream=True,
)
for chunk in stream:
delta = chunk.choices[0].delta.content
if delta:
print(delta, end="")
异步流式使用 async for chunk in await client.chat.completions.create(..., stream=True)。
Message 体系(与原生 openai 的差异)
原生 openai SDK 的 messages 参数是 TypedDict 风格({"role": ..., "content": ...}),
本库改为 langchain 风格的类:
from openai_io import AIMessage, FunctionCall, HumanMessage, SystemMessage, ToolCall, ToolMessage
messages = [
SystemMessage(content="你是助手"),
HumanMessage(content="北京天气如何?"),
AIMessage(
content=None,
tool_calls=[ToolCall(id="call_1", function=FunctionCall(name="get_weather", arguments='{"city": "北京"}'))],
),
ToolMessage(content="晴,25°C", tool_call_id="call_1"),
]
BaseMessage抽象基类:content/additional_kwargs/response_metadata/name/id,type为类别标识("human"/"ai"/"tool"…)content支持多模态 part 列表([{"type": "text", ...}, {"type": "image_url", ...}])- 兼容原始 dict:
messages可以混合传入BaseMessage与{"role": ..., "content": ...}, 迁移时无需一次性替换全部代码 - pydantic 2.13 起构造参数为关键字形式:
HumanMessage(content="你好")
与 openai SDK 的对应关系
| openai SDK | openai-io |
|---|---|
from openai import OpenAI |
from openai_io import OpenAI |
client.chat.completions.create(...) |
client.chat.completions.create(...) |
client.completions.create(...) |
client.completions.create(...) |
client.embeddings.create(...) |
client.embeddings.create(...) |
from openai import AsyncOpenAI |
from openai_io import AsyncOpenAI |
openai.OpenAIError 等异常 |
openai_io.OpenAIError 等,类名一致 |
请求参数(temperature / max_tokens / tools / …) |
同名同语义;未传参不写入请求体(NotGiven 哨兵语义一致) |
| TypedDict messages | langchain 风格 BaseMessage(也可传 dict) |
create 的入口参数与 openai SDK 对齐,含 stream / stream_options / tools /
tool_choice / response_format / seed 等;未显式传参的字段不会出现在请求体中。
开发
uv sync --extra dev
uv run ruff check src tests && uv run ruff format --check src tests
uv run pyright
uv run pytest
测试使用 httpx.MockTransport 注入 mock 响应,无需真实 API key。
许可证
Apache-2.0
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file openai_io-0.1.1.tar.gz.
File metadata
- Download URL: openai_io-0.1.1.tar.gz
- Upload date:
- Size: 24.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.12.3 {"installer":{"name":"uv","version":"0.12.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5424ff350710596a23237c22a02a2f05073c35d5832f62de8d39baae68b2c2f6
|
|
| MD5 |
c0f586e67a92e47bf671d88bdfba57d8
|
|
| BLAKE2b-256 |
74d4eff6f7367d97f650b5d0b5e01a2e2fbd6c67a63d025625427670ab05f09e
|
File details
Details for the file openai_io-0.1.1-py3-none-any.whl.
File metadata
- Download URL: openai_io-0.1.1-py3-none-any.whl
- Upload date:
- Size: 28.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.12.3 {"installer":{"name":"uv","version":"0.12.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
06e223797eb109567dcd5ac5f50a1c095b001b730151410f76d4657971ee786a
|
|
| MD5 |
bc8b7c26d3adc2c7c24e6c35340863ce
|
|
| BLAKE2b-256 |
2a1635b24313940176b7fb429bd3d45f8c98d92cba00efd7686ba188fe8baac6
|