# Reno AI SDK

Official Python client library for the Reno AI API.

[![PyPI version](https://badge.fury.io/py/renoai.svg)](https://badge.fury.io/py/renoai)
[![Python Support](https://img.shields.io/pypi/pyversions/renoai.svg)](https://pypi.org/project/renoai/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

## Features

- 🚀 Simple and intuitive API
- 🔄 Streaming support for real-time responses
- 🛡️ Comprehensive error handling with user-friendly messages
- 🔁 Automatic retry logic with exponential backoff
- ⏱️ Configurable timeouts
- 📝 Full type hints for better IDE support
- 🧪 Well-tested and production-ready

## Installation

```bash
pip install renoai
```

### Development Installation

```bash
git clone https://github.com/yourusername/renoai-sdk.git
cd renoai-sdk
pip install -e ".[dev]"
```

## Quick Start

```python
from renoai import Reno

# Initialize the client
client = Reno(api_key="reno_sk_your_key_here")

# Simple question
answer = client.ask("What is Python?")
print(answer)

# Chat with message history
messages = [
    {"role": "system", "content": "You are a helpful assistant."},
    {"role": "user", "content": "Tell me a joke about programming"}
]
response = client.chat(messages)
print(response.text)
```

## Usage Examples

### Basic Usage

```python
from renoai import Reno

# Create client
client = Reno(api_key="reno_sk_xxx")

# Ask a simple question
answer = client.ask("Explain machine learning in simple terms")
print(answer)

# With custom system message
answer = client.ask(
    prompt="What is recursion?",
    system="You are a computer science professor."
)
print(answer)
```

### Chat Completions

```python
# Multi-turn conversation
messages = [
    {"role": "system", "content": "You are a Python expert."},
    {"role": "user", "content": "How do I read a file in Python?"},
    {"role": "assistant", "content": "You can use open() function..."},
    {"role": "user", "content": "What about CSV files?"}
]

response = client.chat(messages, temperature=0.8)
print(response.text)

# Access metadata
print(f"Model: {response.model}")
print(f"Tokens used: {response.usage.total_tokens}")
```

### Streaming Responses

```python
# Stream responses for real-time output
messages = [{"role": "user", "content": "Write a short story"}]

for chunk in client.chat(messages, stream=True):
    if chunk.delta:
        print(chunk.delta, end="", flush=True)
```

### Advanced Configuration

```python
from renoai import Reno

# Custom configuration
client = Reno(
    api_key="reno_sk_xxx",
    base_url="https://api.reno.ai/v1",
    timeout=60,  # 60 second timeout
    max_retries=5  # Retry up to 5 times
)

# Use different model
response = client.chat(
    messages=[{"role": "user", "content": "Hello!"}],
    model="gemma2:9b-instruct",
    temperature=0.9,
    max_tokens=500
)
```

### Error Handling

```python
from renoai import Reno, RenoError, RenoTimeoutError, RenoConnectionError

client = Reno(api_key="reno_sk_xxx")

try:
    response = client.ask("What is AI?")
    print(response)
except RenoTimeoutError as e:
    print(f"Request timed out: {e}")
except RenoConnectionError as e:
    print(f"Connection failed: {e}")
except RenoError as e:
    print(f"API Error [{e.code}]: {e.message}")
    print(e.user_friendly())  # Get user-friendly error message
```

### Context Manager

```python
# Automatically close connection
with Reno(api_key="reno_sk_xxx") as client:
    response = client.ask("Hello!")
    print(response)
# Session automatically closed
```

## API Reference

### Reno Client

```python
Reno(
    api_key: str,
    base_url: str = "http://127.0.0.1:8000/api/v1",
    timeout: int = 30,
    max_retries: int = 3
)
```

#### Methods

**`ask(prompt, system=None, model="gemma2:2b-instruct", temperature=0.7, max_tokens=None)`**

Simple single-turn question. Returns the response text as a string.

**`chat(messages, model="gemma2:2b-instruct", temperature=0.7, max_tokens=None, stream=False, **kwargs)`**

Full chat completion with message history. Returns `Completion` object or generator if streaming.

**`close()`**

Close the HTTP session.

### Response Objects

**`Completion`**
- `text` / `content`: The generated text
- `id`: Completion ID
- `model`: Model used
- `choices`: List of Choice objects
- `usage`: Usage object with token counts

**`Choice`**
- `content`: Message content
- `role`: Message role
- `finish_reason`: Why generation stopped

**`Usage`**
- `prompt_tokens`: Tokens in prompt
- `completion_tokens`: Tokens in completion
- `total_tokens`: Total tokens used

### Exceptions

- `RenoError`: Base exception for API errors
- `RenoConnectionError`: Connection failures
- `RenoTimeoutError`: Request timeouts

All exceptions have:
- `code`: Error code
- `message`: Error message
- `details`: Additional details
- `user_friendly()`: User-friendly error explanation

## Error Codes

The SDK provides detailed error codes for debugging:

- **1xxx**: Authentication errors (invalid/expired API key)
- **2xxx**: Request validation errors (invalid parameters)
- **3xxx**: Model errors (not found, unavailable)
- **4xxx**: Context/token limit errors
- **5xxx**: Rate limiting errors
- **6xxx**: Server errors
- **7xxx**: Content policy violations
- **8xxx**: Billing/payment errors
- **9xxx**: Internal errors

## Development

### Running Tests

```bash
pytest tests/
pytest --cov=renoai tests/  # With coverage
```

### Code Formatting

```bash
black renoai/
isort renoai/
flake8 renoai/
mypy renoai/
```

### Building Distribution

```bash
python -m build
twine check dist/*
```

### Publishing to PyPI

```bash
# Test PyPI
twine upload --repository testpypi dist/*

# Production PyPI
twine upload dist/*
```

## Requirements

- Python 3.8+
- requests >= 2.25.0
- urllib3 >= 1.26.0

## License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

1. Fork the repository
2. Create your feature branch (`git checkout -b feature/AmazingFeature`)
3. Commit your changes (`git commit -m 'Add some AmazingFeature'`)
4. Push to the branch (`git push origin feature/AmazingFeature`)
5. Open a Pull Request

## Support

- 📧 Email: your.email@example.com
- 🐛 Issues: [GitHub Issues](https://github.com/yourusername/renoai-sdk/issues)
- 📖 Documentation: [GitHub README](https://github.com/yourusername/renoai-sdk#readme)

## Changelog

### 0.1.0 (2025-02-15)

- Initial release
- Basic chat completions
- Streaming support
- Comprehensive error handling
- Retry logic with exponential backoff

## Acknowledgments

Built with ❤️ for the Reno AI community.
