# drprompt

[![PyPI version](https://badge.fury.io/py/drprompt.svg)](https://pypi.org/project/drprompt/)
[![Python 3.8+](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/downloads/)
[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT)

Python SDK for [Dr-Prompt](https://github.com/doktur-ai/dr-prompt) — a lightweight, version-controlled prompt management system.

Store, version, and serve your LLM prompts through a clean API. Use this SDK to fetch prompts at runtime, render templates, track token usage, and more.

## Installation

```bash
pip install drprompt
```

## Quick Start

```python
from drprompt import DrPrompt

# Authenticate with an API key (generate one from Settings > API Keys in the UI)
client = DrPrompt("https://your-instance.com", api_key="drp_your_api_key")

# Fetch a prompt by UID
prompt = client.get_prompt("550e8400-e29b-41d4-a716-446655440000")

# Render template variables
rendered = prompt.render({"topic": "Python", "style": "concise"})
print(rendered)
```

## Usage with OpenAI

```python
from drprompt import DrPrompt
from openai import OpenAI

drp = DrPrompt("https://your-instance.com", api_key="drp_your_api_key")
openai = OpenAI()

prompt = drp.get_prompt("550e8400-e29b-41d4-a716-446655440000")
system_prompt = prompt.render({"topic": "Python"})

response = openai.chat.completions.create(
    model="gpt-4",
    messages=[
        {"role": "system", "content": system_prompt},
        {"role": "user", "content": "Explain decorators"}
    ]
)

# Report token usage back to Dr-Prompt
drp.report_usage(
    prompt=prompt.uid,
    model="gpt-4",
    input_tokens=response.usage.prompt_tokens,
    output_tokens=response.usage.completion_tokens
)
```

## Usage with Anthropic

```python
from drprompt import DrPrompt
import anthropic

drp = DrPrompt("https://your-instance.com", api_key="drp_your_api_key")
claude = anthropic.Anthropic()

prompt = drp.get_prompt("550e8400-e29b-41d4-a716-446655440000")
system_prompt = prompt.render({"topic": "Python"})

response = claude.messages.create(
    model="claude-sonnet-4-5-20250929",
    max_tokens=1024,
    system=system_prompt,
    messages=[{"role": "user", "content": "Explain decorators"}]
)

drp.report_usage(
    prompt=prompt.uid,
    model="claude-sonnet-4-5",
    input_tokens=response.usage.input_tokens,
    output_tokens=response.usage.output_tokens
)
```

## Authentication

### API key (recommended)

Generate a key from the Dr-Prompt web UI under **Settings > API Keys**:

```python
client = DrPrompt("https://your-instance.com", api_key="drp_your_api_key")
```

Or load from an environment variable:

```python
import os
client = DrPrompt("https://your-instance.com", api_key=os.environ["DRPROMPT_API_KEY"])
```

### Username / password

```python
client = DrPrompt("https://your-instance.com")
client.login("username", "password")
```

### JWT token

```python
client = DrPrompt("https://your-instance.com", token="your-jwt-token")
```

## Features

### Prompt CRUD

```python
# List all prompts
for p in client.list_prompts():
    print(f"{p.uid}: {p.name}")

# Create
prompt = client.create_prompt(
    name="Code Reviewer",
    content="You are a {{language}} code reviewer. Review for {{focus}}.",
    description="Reviews code for best practices"
)

# Update (creates a new version)
client.update_prompt(prompt.uid, content="Updated content...")

# Delete
client.delete_prompt(prompt.uid)
```

### Version History

```python
versions = client.get_prompt_versions(prompt.uid)
v1 = client.get_prompt_version(prompt.uid, version=1)
print(v1.content)
```

### Template Variables

```python
prompt = client.get_prompt("550e8400-e29b-41d4-a716-446655440000")

# Extract variable names
variables = prompt.get_variables()  # ["language", "focus"]

# Render
rendered = prompt.render({"language": "Python", "focus": "security"})
```

### Collections

```python
collections = client.list_collections()

collection = client.create_collection(
    name="Code Review Prompts",
    description="Prompts for code review tasks",
    color="#00ff88"
)

client.add_prompts_to_collection(collection.id, prompt_ids=[1, 2, 3])
```

### Usage Tracking

```python
# Report usage after an LLM call
client.report_usage(
    prompt=prompt.uid,
    model="gpt-4",
    input_tokens=150,
    output_tokens=320
)

# Get stats
stats = client.get_usage_stats()
print(f"Total calls: {stats.total_calls}")
print(f"Total tokens: {stats.total_tokens}")
```

### Smart Features

Requires an OpenAI API key configured on your Dr-Prompt instance.

```python
# Analyze prompt quality
analysis = client.analyze_prompt(prompt.uid)

# Get AI-suggested improvements
improved = client.improve_prompt(prompt.uid, focus="clarity")

# Generate variations
variations = client.generate_variations(prompt.uid, count=3, style="formal")
```

## Error Handling

```python
from drprompt import DrPrompt, AuthenticationError, NotFoundError, APIError

client = DrPrompt("https://your-instance.com", api_key="drp_your_api_key")

try:
    prompt = client.get_prompt("nonexistent")
except AuthenticationError:
    print("Invalid or expired API key")
except NotFoundError:
    print("Prompt not found")
except APIError as e:
    print(f"API error ({e.status_code}): {e.message}")
```

## Configuration

```python
client = DrPrompt(
    base_url="https://your-instance.com",
    api_key="drp_your_api_key",  # or token="jwt-token"
    timeout=30,                   # request timeout in seconds
)
```

## Links

- [Dr-Prompt GitHub](https://github.com/doktur-ai/dr-prompt) — self-host the server
- [API Docs](https://your-instance.com/docs) — Swagger UI on every instance at `/docs`
- [Issues](https://github.com/doktur-ai/dr-prompt/issues) — bug reports and feature requests

## License

MIT
