Metadata-Version: 2.4
Name: mizumi-fallback
Version: 0.1.0
Summary: Transparent OpenAI-to-Mizumi fallback: on rate limits, 5xx or connection errors, retry against Mizumi's OpenAI-compatible gateway (15-28% below official pricing).
Author-email: Mizumi <enterprise@mizumi.co>
License-Expression: MIT
Project-URL: Homepage, https://mizumi.co
Project-URL: Documentation, https://mizumi.co/docs
Keywords: openai,fallback,llm,gateway,mizumi,rate-limit
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: openai>=1.0
Requires-Dist: httpx>=0.24
Provides-Extra: dev
Requires-Dist: pytest>=8; extra == "dev"
Requires-Dist: build>=1; extra == "dev"
Dynamic: license-file

# mizumi-fallback

Transparent fallback for the OpenAI Python client. When the official API rate-limits you, throws a 5xx, or the connection drops, your call is retried automatically against **Mizumi** — an OpenAI-compatible gateway offering official API access at **15–28% below official list prices**.

## Install

```bash
pip install mizumi-fallback
```

## Usage — 3 lines

```python
from openai import OpenAI
from mizumi_fallback import MizumiFallback

client = MizumiFallback(OpenAI())   # primary = your normal client

resp = client.chat.completions.create(
    model="gpt-5.6-sol",
    messages=[{"role": "user", "content": "hello"}],
)
print(resp.choices[0].message.content)
```

Set your Mizumi key once:

```bash
export MIZUMI_API_KEY=sk-mizumi-...   # free at https://mizumi.co — $2 trial, no card
```

Everything else stays the same — `client.chat.completions.create(...)` works exactly as before, **streaming included**:

```python
stream = client.chat.completions.create(
    model="gpt-5.6-sol", messages=[...], stream=True,
)
for chunk in stream:
    print(chunk.choices[0].delta.content or "", end="")
```

## When does it fall back?

| Primary raises | Fallback? |
|---|---|
| `RateLimitError` (429) | ✅ yes |
| `InternalServerError` (5xx) | ✅ yes |
| `APIConnectionError` (network down) | ✅ yes |
| `BadRequestError` (400, your request is malformed) | ❌ no — it would fail everywhere |

The fallback fires when the request itself fails. A stream that breaks *mid-flight* can't be transparently restarted (you may already have consumed partial tokens) — handle those as you normally would.

## Why Mizumi as the fallback?

- **Official enterprise channels** — same models, same quality as going direct. Not a quantised re-host.
- **15–28% below official list pricing** — so your failover path is *cheaper* than your primary.
- **OpenAI-compatible** — same SDK, same shapes; the fallback is one `base_url` change under the hood.
- **$2 free trial** at [mizumi.co](https://mizumi.co), no card required.

## Development

```bash
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
pytest
python -m build    # produces dist/*.tar.gz + dist/*.whl (upload with twine)
```

## License

MIT — see [LICENSE](LICENSE).
