Metadata-Version: 2.4
Name: answerkit
Version: 0.1.0
Summary: A lightweight, standalone Python AI SDK for building Q&A applications with Groq, async streaming, model fallback, conversation context, optional Google Serper web search, and prompt enhancement.
Author-email: Mahadev Athani <mahadevathani1729@gmail.com>
License-Expression: MIT
Project-URL: Homepage, https://github.com/Mahadev1729/QnAChatBot
Project-URL: Repository, https://github.com/Mahadev1729/QnAChatBot
Project-URL: Issues, https://github.com/Mahadev1729/QnAChatBot/issues
Keywords: ai,sdk,groq,llm,qa,question-answering,search,serper,streaming,rag
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 :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Operating System :: OS Independent
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: groq>=0.9.0
Requires-Dist: httpx>=0.27.0
Requires-Dist: python-dotenv>=1.0.0
Provides-Extra: dev
Requires-Dist: pytest>=8.0.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.23.0; extra == "dev"
Requires-Dist: build>=1.0.0; extra == "dev"
Requires-Dist: twine>=5.0.0; extra == "dev"
Requires-Dist: ruff>=0.4.0; extra == "dev"
Dynamic: license-file

# AnswerKit ⚡

> **A lightweight, standalone Python AI SDK for building Q&A applications with Groq, async streaming, model fallback, conversation context, optional Google Serper web search, and prompt enhancement.**

---

[![Python Version](https://img.shields.io/badge/python-3.9%2B-blue.svg)](https://www.python.org/downloads/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Async Ready](https://img.shields.io/badge/async-ready-green.svg)](#async-first-design)

---

## 🌟 Overview

**AnswerKit** is an open-source, framework-independent Python SDK designed to make adding state-of-the-art AI-powered Q&A capabilities to your applications effortless.

Whether you are building a **FastAPI backend**, a **Flask app**, a **CLI utility**, a **Discord bot**, or a **full AI SaaS platform**, AnswerKit gives you a clean, async-first API that handles:

- **Ultra-fast LLM generation** powered by [Groq](https://groq.com)
- **Token streaming** via native Python async generators
- **Automatic model fallback cascades** for rock-solid uptime and zero-downtime rate-limit resilience
- **Multi-turn conversation context** without forcing any database dependencies
- **Live web search integration** via [Google Serper](https://serper.dev) for fresh, up-to-date facts
- **Prompt engineering & polishing** to transform vague user inputs into optimal LLM prompts
- **Safe, zero-leak credential configuration** and developer-friendly error handling

---

## 🚀 Why AnswerKit?

| Challenge | Without AnswerKit | With AnswerKit |
|---|---|---|
| **Model Availability** | Single model failure crashes user requests | Automatic fallback cascade across models |
| **Streaming** | Tied to web frameworks like FastAPI `StreamingResponse` | Native async generator usable anywhere (FastAPI, CLI, WebSockets, Bot) |
| **Fresh Information** | Manual search scraping, parsing, prompt formatting | Built-in smart keyword detection and Serper context injection |
| **Database Ties** | Heavy ORMs and tables required just to talk to LLMs | Pure in-memory context lists; use any database you want |
| **Speed** | Slow inference bottlenecks | Ultra-fast Groq LPU inference |

---

## 📦 Installation

```bash
pip install answerkit
```

For local development and running tests:

```bash
git clone https://github.com/Mahadev1729/QnAChatBot.git
cd QnAChatBot/answerkit
pip install -e ".[dev]"
```

---

## 🔑 API Keys & Configuration

| Service | Environment Variable | Status | Purpose |
|---|---|---|---|
| **Groq** | `GROQ_API_KEY` | **Required** | LLM inference, streaming, and prompt polishing |
| **Google Serper** | `SERPER_API_KEY` | **Optional** | Live Google search (Required **only** when `enable_web_search=True`) |

### Configuration Precedence:
1. **Explicit constructor argument** (`AnswerKit(groq_api_key="...", ...)`)
2. **Environment variable** (`GROQ_API_KEY`, `SERPER_API_KEY`, `ANSWERKIT_MODEL`, `ANSWERKIT_ENABLE_WEB_SEARCH`)
3. **Default SDK fallback**

### Environment File (`.env`):

```bash
GROQ_API_KEY=gsk_your_groq_api_key_here
SERPER_API_KEY=your_serper_api_key_here
ANSWERKIT_MODEL=openai/gpt-oss-20b
ANSWERKIT_ENABLE_WEB_SEARCH=false
```

---

## ⚡ Quick Start

### 1. Basic Q&A

```python
import asyncio
from answerkit import AnswerKit

async def main():
    ai = AnswerKit(groq_api_key="YOUR_GROQ_API_KEY")
    
    answer = await ai.ask("Explain Retrieval Augmented Generation in 2 sentences.")
    print(answer)

if __name__ == "__main__":
    asyncio.run(main())
```

### 2. Async Token Streaming

Stream tokens in real-time as they are generated by the model:

```python
import asyncio
from answerkit import AnswerKit

async def main():
    ai = AnswerKit(groq_api_key="YOUR_GROQ_API_KEY")
    
    async for chunk in ai.stream("Explain how JWT authentication works"):
        print(chunk, end="", flush=True)

if __name__ == "__main__":
    asyncio.run(main())
```

### 3. Multi-Turn Conversation Context

Pass previous conversation history without needing a database:

```python
import asyncio
from answerkit import AnswerKit

async def main():
    ai = AnswerKit(groq_api_key="YOUR_GROQ_API_KEY")
    
    history = [
        {"role": "user", "content": "What is Python?"},
        {"role": "assistant", "content": "Python is a high-level programming language."}
    ]
    
    answer = await ai.ask("What are its primary design philosophies?", conversation_history=history)
    print(answer)

if __name__ == "__main__":
    asyncio.run(main())
```

### 4. Web-Augmented Answers (Google Serper)

Enable live web search to answer queries regarding current news, latest releases, and real-time events:

```python
import asyncio
from answerkit import AnswerKit

async def main():
    ai = AnswerKit(
        groq_api_key="YOUR_GROQ_API_KEY",
        serper_api_key="YOUR_SERPER_API_KEY",
        enable_web_search=True
    )
    
    # Simple string answer with web search context
    answer = await ai.ask("What are the latest developments in quantum computing today?")
    print(answer)
    
    # Or get structured metadata including source citations
    result = await ai.ask_with_metadata("What is the current stock price of Apple?")
    print("Content:", result.content)
    print("Search Used:", result.used_search)
    print("Sources:", [s.link for s in result.sources])

if __name__ == "__main__":
    asyncio.run(main())
```

### 5. Automatic Model Fallback

AnswerKit automatically falls back through configured models if the primary model encounters rate limits (429), decommission errors (404), or temporary outages:

```python
ai = AnswerKit(
    groq_api_key="YOUR_GROQ_API_KEY",
    model="openai/gpt-oss-120b",
    fallback_models=[
        "openai/gpt-oss-20b",
        "llama-3.3-70b-versatile",
        "llama-3.1-8b-instant"
    ]
)
```

### 6. Prompt Polishing

Enhance draft or vague user prompts using ultra-fast LLMs:

```python
improved_prompt = await ai.polish_prompt("build me a chatbot")
print(improved_prompt)
# Output: "Design an end-to-end architecture for an intelligent conversational chatbot, specifying the backend framework, state management, LLM orchestration, and API integrations."
```

---

## 🌐 Framework Integrations

### FastAPI Integration

```python
from fastapi import FastAPI
from fastapi.responses import StreamingResponse
from answerkit import AnswerKit

app = FastAPI(title="AI API powered by AnswerKit")
ai = AnswerKit()

@app.post("/api/ask")
async def ask_endpoint(question: str):
    answer = await ai.ask(question)
    return {"answer": answer}

@app.get("/api/stream")
async def stream_endpoint(question: str):
    async def event_publisher():
        async for chunk in ai.stream(question):
            yield f"data: {chunk}\n\n"
    return StreamingResponse(event_publisher(), media_type="text/event-stream")
```

### Flask Integration

```python
import asyncio
from flask import Flask, request, jsonify
from answerkit import AnswerKit

app = Flask(__name__)
ai = AnswerKit()

@app.route("/ask", methods=["POST"])
def ask():
    question = request.json.get("question", "")
    answer = asyncio.run(ai.ask(question))
    return jsonify({"answer": answer})
```

### CLI Application

```python
import asyncio
from answerkit import AnswerKit

async def cli():
    ai = AnswerKit()
    print("🤖 AnswerKit CLI (Type 'exit' to quit)\n")
    while True:
        prompt = input("You > ")
        if prompt.lower() in ("exit", "quit"):
            break
        print("AI > ", end="", flush=True)
        async for token in ai.stream(prompt):
            print(token, end="", flush=True)
        print("\n")

if __name__ == "__main__":
    asyncio.run(cli())
```

---

## 🛡️ Error Handling

AnswerKit provides a clean hierarchy of custom exceptions:

```python
from answerkit import (
    AnswerKit,
    AnswerKitError,
    ConfigurationError,
    ModelError,
    WebSearchError,
)

try:
    ai = AnswerKit()
    answer = await ai.ask("Hello world")
except ConfigurationError as e:
    print(f"Configuration issue: {e}")
except ModelError as e:
    print(f"Model generation failure across all fallbacks: {e}")
except WebSearchError as e:
    print(f"Web search error: {e}")
except AnswerKitError as e:
    print(f"General SDK error: {e}")
```

---

## 🧪 Testing

AnswerKit includes an extensive test suite with 100% mocked external calls (zero live API tokens required):

```bash
# Run tests with pytest
pytest -v
```

---

## 🔨 Building & Packaging

To create wheel and source distributions:

```bash
python -m build
```

This generates distribution archives in `dist/`:
- `dist/answerkit-0.1.0-py3-none-any.whl`
- `dist/answerkit-0.1.0.tar.gz`

To install the locally built wheel:

```bash
pip install dist/answerkit-0.1.0-py3-none-any.whl
```

---

## 🚀 Manual PyPI Publishing

When ready to publish to PyPI:

1. Build distributions:
   ```bash
   python -m build
   ```
2. Upload to TestPyPI (optional):
   ```bash
   twine upload --repository testpypi dist/*
   ```
3. Upload to official PyPI:
   ```bash
   twine upload dist/*
   ```

*(AnswerKit package name availability on PyPI verified for initial release).*

---

## 📄 License

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