Metadata-Version: 2.4
Name: openai_sqlite_cache
Version: 0.0.3
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` is an unofficial, transparent SQLite cache for the
OpenAI Python SDK. When the same API endpoint and model receive exactly the
same input again, the cached response is returned without another upstream
request.

Both the PyPI distribution and the Python import package are named
`openai_sqlite_cache` (the distribution name is normalized as
`openai-sqlite-cache`). Existing OpenAI SDK code only needs an import
replacement.

## Installation

Install from PyPI:

```bash
pip install openai_sqlite_cache
```

Install from a local checkout:

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

> **Upgrading from 0.0.1 or 0.0.2:** replace `import cached_openai` with
> `import openai_sqlite_cache`. Version 0.0.3 changed the import package name
> to avoid a namespace collision with the existing `cached-openai` project.

## Usage

Keep the local `openai` alias and replace only the import:

```python
# Before: import openai
import openai_sqlite_cache as openai

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

Using the import package directly also works:

```python
import openai_sqlite_cache

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

The following official SDK patterns remain available:

- `OpenAI`, `AsyncOpenAI`, `AzureOpenAI`, and `AsyncAzureOpenAI`;
- module-level calls such as `openai.chat.completions.create(...)`;
- `with_options()`, `with_raw_response`, and `with_streaming_response`;
- custom `base_url` values and custom synchronous or asynchronous HTTP clients;
- official SDK response models and exception types.

A streaming response is cached after it has been fully consumed. If a stream
is closed early, its incomplete contents are not cached. Realtime/WebSocket
traffic does not use ordinary HTTP requests and is not cached.

## Cache keys and endpoint scope

Cache keys use SHA-256 and include:

- the HTTP method and normalized full API URL;
- the request body (JSON keys are sorted, while multipart boundaries are
  ignored and uploaded file contents are hashed);
- the model name;
- semantic request headers such as organization, project, and beta headers;
- a one-way credential-scope hash that prevents responses from being shared
  across API keys.

Request bodies and API keys are never stored in the database. The database
contains only request hashes, successful response bodies, required response
headers, and hit statistics. Entries do not expire by default, and only 2xx
responses are cached.

To avoid incorrectly deduplicating operations with side effects, caching is
limited to inference and generation endpoints: Responses, Chat Completions,
Completions, Embeddings, Moderations, Images, Audio, and Videos. Management
APIs such as Files, Uploads, Batches, Fine-tuning, and Vector Stores always
reach the upstream service.

## Configuration

By default, the database is created in the current working directory:

```text
./llm_api_cache.sqlite3
```

Environment variables can override the defaults:

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

Global configuration must be applied before creating a client:

```python
import openai_sqlite_cache as openai

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

Individual clients can override the global configuration:

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

Cache maintenance helpers are also available:

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

The cache may contain sensitive model responses and should be protected like
other local application data. The package attempts to set directory and
database permissions to `0700` and `0600`, respectively.

## Development

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