Metadata-Version: 2.4
Name: freemodel-claude
Version: 0.2.0
Summary: Lightweight client for FreeModel's Claude endpoint with retry logic, graceful error handling, and extended thinking support.
Project-URL: Repository, https://pypi.org/project/freemodel-claude/
Author: Anonymous
License-Expression: MIT
License-File: LICENSE
Keywords: ai,anthropic,claude,freemodel,llm
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Requires-Python: >=3.10
Requires-Dist: httpx>=0.27
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff; extra == 'dev'
Description-Content-Type: text/markdown

# freemodel-claude

Lightweight Python client for [FreeModel](https://freemodel.dev)'s Claude endpoint. Use Anthropic Claude models (Opus, Sonnet, Haiku) with just a FreeModel API key.

## Install

```bash
pip install freemodel-claude
```

## Quick start

```python
from freemodel_claude import ClaudeClient

client = ClaudeClient("your-api-key-here")

# Simple ask
response = client.ask("What is 2+2?")
print(response.text)  # "4"

# Pick a model
response = client.ask("Write a haiku", model="claude-opus-4-8")
print(response.text)

# Streaming
for chunk in client.stream("Tell me a story"):
    print(chunk, end="", flush=True)

# System prompt
response = client.ask("Debug this", system="You are a senior Python developer.")

# Full metadata
response = client.ask("Explain quantum computing")
print(response.text)
print(response.usage)     # token counts, model, stop reason
```

## Models

| Model | Description |
|---|---|
| `claude-opus-4-8` | Opus 4.8 — most capable |
| `claude-opus-4-7` | Opus 4.7 |
| `claude-sonnet-4-6` | Sonnet 4.6 — balanced (default) |
| `claude-opus-4-6` | Opus 4.6 |
| `claude-haiku-4-5-20251001` | Haiku 4.5 — fastest |

```python
client.models()  # tuple of available model names
```

Invalid model names raise `ValueError`.

## Thinking

Extended thinking is enabled by default (`thinking_budget=4095`). The upstream API redacts thinking output — `response.thinking` will always be empty, but `response.usage.thinking_tokens` reports the count.

Disable thinking to save tokens:

```python
response = client.ask("Hi", thinking_budget=None)
```

## Error handling

All errors raise subclasses of `FreeModelError`:

| Exception | When |
|---|---|
| `AuthError` | Invalid API key (401/403) |
| `RateLimitError` | Rate limited (429) |
| `APIError` | Other HTTP errors (status + body) |
| `ConnectionError` | Network failure (timeout, DNS, etc.) |

```python
from freemodel_claude import ClaudeClient, AuthError, RateLimitError

client = ClaudeClient("bad-key")
try:
    client.ask("Hi")
except AuthError:
    print("Invalid key")
except RateLimitError:
    print("Slow down")
```

## Context manager

Reuses the underlying HTTP connection across requests:

```python
with ClaudeClient("your-api-key") as client:
    r1 = client.ask("Hello")
    r2 = client.ask("Goodbye")
```

## API key

Get one at [freemodel.dev](https://freemodel.dev). Pass it to the constructor or set `FREEMODEL_API_KEY`:

```python
import os
client = ClaudeClient(os.environ["FREEMODEL_API_KEY"])
```

## Requirements

- Python >= 3.10
- httpx >= 0.27
