Metadata-Version: 2.4
Name: openai_sqlite_cache
Version: 0.0.1
Summary: An unofficial drop-in OpenAI Python SDK with a local SQLite response cache
Author: openai_sqlite_cache contributors
License-Expression: MIT
Keywords: openai,cache,sqlite,llm,api
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: openai<3,>=1.66.2
Dynamic: license-file

# openai_sqlite_cache

`openai_sqlite_cache` 是非官方的 OpenAI Python SDK 透明 SQLite 缓存层。同一个 API、同一个模型、完全相同的输入再次调用时，会直接返回本机缓存的响应，不再请求上游。

PyPI 分发名是 `openai_sqlite_cache`（规范化名称为 `openai-sqlite-cache`）；为满足只替换 import 的用法，Python 导入名仍然是 `cached_openai`。

## 安装

在当前仓库中安装：

```bash
pip install ./openai_sqlite_cache
```

发布到你有权限的 Python 包索引后，安装形式为：

```bash
pip install openai_sqlite_cache
```

> 注意：本项目与公共 PyPI 上的 `cached-openai` 分发项目都提供 `cached_openai` 导入包，二者不能安全地安装在同一个 Python 环境中。请只安装其中一个。

## 用法

现有代码只需替换 import，并保留 `openai` 这个本地别名：

```python
# 原来：import openai
import cached_openai as openai

client = openai.OpenAI()
response = client.responses.create(
    model="gpt-5",
    input="Explain SQLite in one sentence.",
)
print(response.output_text)
```

也可以直接使用包名：

```python
import cached_openai

client = cached_openai.OpenAI()
completion = client.chat.completions.create(
    model="gpt-4.1-mini",
    messages=[{"role": "user", "content": "Hello"}],
)
```

以下官方 SDK 用法均保持不变：

- `OpenAI`、`AsyncOpenAI`、`AzureOpenAI` 和 `AsyncAzureOpenAI`；
- 模块级调用，如 `openai.chat.completions.create(...)`；
- `with_options()`、`with_raw_response`、`with_streaming_response`；
- 自定义 `base_url` 和自定义同步/异步 `http_client`；
- 官方 SDK 的响应模型和异常类型。

流式响应会在第一次被完整消费时写入缓存；如果流被提前关闭，则不会缓存不完整内容。Realtime/WebSocket 不经过普通 HTTP 请求，因此不会缓存。

## 缓存规则

缓存键使用 SHA-256 计算，包含：

- HTTP 方法和规范化后的完整 API URL；
- 请求体（JSON 会按键排序，multipart 会忽略随机 boundary 并对文件内容取 hash）；
- 模型名；
- organization、project、beta 等会影响语义的请求头；
- API 凭据的不可逆作用域 hash，防止不同 API key 之间共享响应。

请求原文和 API key 都不会写入数据库。数据库只保存 hash、成功响应体、必要响应头和命中统计。默认永久保留，只缓存 2xx 响应。

为避免有副作用的操作被错误去重，目前只缓存这些推理/生成端点：Responses、Chat Completions、Completions、Embeddings、Moderations、Images、Audio 和 Videos。Files、Uploads、Batches、Fine-tuning、Vector Stores 等管理类 API 会原样请求上游。

## 配置

默认数据库位置：

- macOS：`~/Library/Caches/openai-sqlite-cache/cache.sqlite3`
- Linux：`$XDG_CACHE_HOME/openai-sqlite-cache/cache.sqlite3`，未设置时使用 `~/.cache/...`
- Windows：`%LOCALAPPDATA%/openai-sqlite-cache/cache.sqlite3`

环境变量：

```bash
export CACHED_OPENAI_CACHE_PATH=/path/to/cache.sqlite3
export CACHED_OPENAI_TTL_SECONDS=86400
export CACHED_OPENAI_DISABLE=0
```

也可以在创建客户端前配置：

```python
import cached_openai as openai

openai.configure_cache(
    path="./.cache/openai.sqlite3",
    ttl_seconds=24 * 60 * 60,
)
client = openai.OpenAI()
```

单个客户端可以覆盖全局配置：

```python
client = openai.OpenAI(
    cache_path="./project-cache.sqlite3",
    cache_ttl=3600,
    cache_enabled=True,
)
```

维护接口：

```python
print(openai.cache_info())
removed = openai.clear_cache()
```

缓存文件可能包含模型响应中的敏感内容，应像其他本地应用数据一样保护。包会尽量把目录和数据库权限分别设为 `0700` 和 `0600`。

## 开发与测试

```bash
cd openai_sqlite_cache
python -m unittest discover -s tests -v
python -m pip wheel --no-deps . -w dist
```
