debuggai 0.2.0
Python SDK for DebuggAI API
License: MIT
Requires Python: >=3.10

# DebuggAI Python SDK

Python SDK for the DebuggAI API. Provides a unified interface for E2E test generation,
execution, and artifact management.

## 🤖 AI Agent Quick Start

**For AI agents working with DebuggAI API:**

```python
from debuggai import DebuggAIClient

# Authenticate
client = DebuggAIClient.from_api_key(api_key)

# Core workflow: Create → Poll → Download → Analyze
suite = client.e2e.create_suite(repo_name="repo", repo_path="/path", commit_hash="hash")
completed = client.e2e.poll_suite(suite.uuid, timeout=300)

# Check status
if completed.status == "completed":
    files = client.artifacts.download_suite_artifacts(suite.uuid, output_dir)
    # Analyze test files...
elif completed.status == "failed":
    # Handle failure...
```

**Key Methods:**
- `client.e2e.create_suite()` - Generate E2E tests
- `client.e2e.poll_suite(uuid, timeout)` - Wait for completion
- `client.artifacts.download_suite_artifacts(uuid, output_dir)` - Get test files
- `client.e2e.list_suites()` - List all suites
- `client.e2e.get_suite(uuid)` - Get suite details

**Authentication Types:**
- API Key: `DebuggAIClient.from_api_key("key")`
- Token: `DebuggAIClient.from_token("token")`

**Error Handling:**
```python
from debuggai.exceptions import DebuggAIError, AuthenticationError, ValidationError

try:
    suite = client.e2e.create_suite(...)
except AuthenticationError:
    # Invalid credentials
except ValidationError:
    # Invalid parameters
except DebuggAIError as e:
    # Other API errors
    print(f"Error: {e}")
```

## Installation

```bash
pip install debuggai-sdk
```

Or install from source:

```bash
cd debuggai-sdk
pip install -e ".[dev]"
```

## Quick Start

```python
from debuggai import DebuggAIClient

# Create client
client = DebuggAIClient.from_api_key("your-api-key")

# Create E2E test suite
suite = client.e2e.create_suite(
    repo_name="my-repo",
    repo_path="/path/to/repo",
    commit_hash="abc123",
)

# Poll for completion
completed = client.e2e.poll_suite(suite.uuid, timeout=300)

print(f"Suite status: {completed.status}")

# Download artifacts
from pathlib import Path
files = client.artifacts.download_suite_artifacts(
    completed.uuid,
    output_dir=Path("./artifacts"),
)

# Clean up
client.close()
```

Or use as context manager:

```python
with DebuggAIClient.from_api_key("key") as client:
    suite = client.e2e.create_suite(...)
```

## Authentication

The SDK supports two authentication types:

- **Bearer** (default): `Authorization: Bearer <api_key>`
- **Token**: `Authorization: Token <api_key>`

```python
# Bearer auth (default)
client = DebuggAIClient.from_api_key("key")

# Token auth (for some endpoints)
client = DebuggAIClient.from_api_key("key", auth_type="token")
```

## Services

### E2E Service

```python
# Create suite
suite = client.e2e.create_suite(
    repo_name="my-repo",
    repo_path="/path/to/repo",
    commit_hash="abc123",
    changes=[{"status": "modified", "file": "src/main.py"}],
)

# Get suite status
suite = client.e2e.get_suite(suite.uuid)

# Poll until complete
suite = client.e2e.poll_suite(suite.uuid, timeout=300, interval=5)

# List tests for a project
tests = client.e2e.list_tests("my-project")

# Trigger a run
run = client.e2e.create_run("my-project", target_url="http://localhost:3000")

# Poll run
run = client.e2e.poll_run(run.id)
```

### Artifact Service

```python
from pathlib import Path

# Download all artifacts
files = client.artifacts.download_suite_artifacts(
    "suite-uuid",
    output_dir=Path("./artifacts"),
)

# Download specific artifact types
files = client.artifacts.download_suite_artifacts(
    "suite-uuid",
    output_dir=Path("./artifacts"),
    include=["scripts", "recordings"],  # Skip results
)
```

## Error Handling

```python
from debuggai import DebuggAIClient
from debuggai.exceptions import (
    AuthenticationError,
    NotFoundError,
    RateLimitError,
    TimeoutError,
)

client = DebuggAIClient.from_api_key("key")

try:
    suite = client.e2e.create_suite(...)
except AuthenticationError:
    print("Invalid API key")
except RateLimitError as e:
    print(f"Rate limited, retry after {e.retry_after}s")
except TimeoutError as e:
    print(f"Operation timed out after {e.elapsed}s")
except NotFoundError:
    print("Resource not found")
```

## Configuration

```python
from debuggai import DebuggAIClient
from debuggai.config import DebuggAIConfig

config = DebuggAIConfig(
    api_key="your-key",
    base_url="https://api.debugg.ai",
    auth_type="bearer",
    timeout=30.0,
    max_retries=3,
    retry_delay=1.0,
)

client = DebuggAIClient(config=config)
```

## Design Principles

1. **No magic values** - All configuration is explicit
2. **No env var discovery** - API key must be passed explicitly
3. **Typed exceptions** - Clear error handling
4. **Retry logic** - Automatic retries for transient failures
5. **Consistent auth** - Handles Bearer/Token formats correctly

## ⏺ The Testing Philosophy

### The Process
1. Investigate Why Tests Missed It
2. Write Test That FAILS
3. Fix The Code
4. Test Now PASSES

### The Philosophy
Never fix a bug you can't reproduce in a test.