Metadata-Version: 2.4
Name: fewertokens
Version: 0.2.1
Summary: FewerTokens Python SDK — control-plane routing with local LiteLLM dispatch
License-Expression: MIT
Classifier: Development Status :: 4 - Beta
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: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: httpx>=0.25.0
Requires-Dist: pydantic>=2.0.0
Requires-Dist: litellm>=1.40.0
Provides-Extra: dev
Requires-Dist: pytest>=7.4.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.23.0; extra == "dev"
Requires-Dist: respx>=0.21.0; extra == "dev"
Requires-Dist: ruff>=0.1.0; extra == "dev"
Dynamic: license-file

# fewertokens

Python SDK for **FewerTokens** — a control-plane client for cross-family LLM routing.

The SDK asks FewerTokens which provider/model to use, then calls that model **locally** via [LiteLLM](https://github.com/BerriAI/litellm) with your provider keys. Usage is reported back asynchronously.

## Install

```bash
pip install fewertokens
```

## Quick start

```python
from fewertokens import FewerTokens

ft = FewerTokens(
    api_key="ft_live_...",
    openai_api_key="sk-proj-...",      # Optional
    anthropic_api_key="sk-ant-...",    # Optional
    gemini_api_key="AIzaSy...",        # Optional
    base_url="https://api.fewertokens.in",
)

response = ft.chat.completions.create(
    messages=[{"role": "user", "content": "What is Python?"}],
)
print(response.content)
print(response.routing.provider, response.routing.model_used)
print(response.usage)
```

## How it works

1. **Route handshake** — `POST /v1/route` with prompt text + `available_providers`
2. **Local dispatch** — `litellm.completion` / `acompletion` with the routed provider key
3. **Telemetry** — background `POST /v1/telemetry` with `route_id` + token usage (never blocks or raises)

## Privacy & Security

🔒 **Privacy & Security First:**

- **Zero Key Exposure:** Your provider keys stay strictly in your client runtime's RAM memory and are never sent to FewerTokens servers.
- **Direct Local Execution:** Prompt content and response streams flow directly between your machine and LLM provider endpoints (OpenAI, Anthropic, Gemini, etc.). FewerTokens only processes prompt text for routing decisions (~20ms) and never sees or logs completion payloads.

## Streaming

```python
for chunk in ft.chat.completions.create(
    messages=[{"role": "user", "content": "Explain Docker"}],
    stream=True,
):
    print(chunk.content, end="", flush=True)
```

## Async

```python
response = await ft.chat.completions.acreate(
    messages=[{"role": "user", "content": "Hello!"}],
)
```

## Notes

- At least one of `openai_api_key`, `anthropic_api_key`, or `gemini_api_key` is required.
- String shorthand: `prompt="Hello"` is accepted as an alternative to `messages=`.
