Metadata-Version: 2.4
Name: wackypod
Version: 0.1.0
Summary: Official Python SDK for WackyPod - AI-powered text-to-podcast platform
Author-email: WackyPod Team <support@wackypod.com>
License-Expression: MIT
Project-URL: Homepage, https://wackypod.com
Project-URL: Documentation, https://docs.wackypod.com
Project-URL: Source, https://github.com/ferax564/wackypod-python
Project-URL: Issues, https://github.com/ferax564/wackypod-python/issues
Project-URL: Changelog, https://github.com/ferax564/wackypod-python/blob/main/CHANGELOG.md
Keywords: wackypod,podcast,ai,tts,text-to-speech,api,sdk
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
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: Programming Language :: Python :: 3.13
Classifier: Topic :: Multimedia :: Sound/Audio
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: requests>=2.28.0
Provides-Extra: dev
Requires-Dist: pytest>=7.0.0; extra == "dev"
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
Requires-Dist: black>=23.0; extra == "dev"
Requires-Dist: flake8>=6.0.0; extra == "dev"
Requires-Dist: mypy>=1.0; extra == "dev"
Requires-Dist: types-requests>=2.28.0; extra == "dev"
Dynamic: license-file

# WackyPod Python SDK

[![PyPI version](https://img.shields.io/pypi/v/wackypod.svg)](https://pypi.org/project/wackypod/)
[![Python versions](https://img.shields.io/pypi/pyversions/wackypod.svg)](https://pypi.org/project/wackypod/)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)

Official Python SDK for [WackyPod](https://wackypod.com) -- the AI-powered text-to-podcast platform. Transform any content into professional-quality podcasts with just a few lines of code.

## Features

- **Episode Generation** -- Create podcasts from URLs or raw text with configurable presets (quick, standard, deep, extended)
- **Multi-Speaker Dialogue** -- Generate single-host or multi-host conversational podcasts
- **Webhook Management** -- Set up real-time notifications for episode completion, failure, and other events
- **User and Quota Management** -- Check account profile, tier, and monthly usage
- **Async Polling** -- Built-in `wait_for_completion` with configurable timeout and poll interval
- **Typed Models** -- Dataclass-based response objects (`Episode`, `Webhook`, `User`) for IDE autocompletion
- **Comprehensive Error Handling** -- Typed exceptions for authentication, validation, rate limiting, and server errors
- **PEP 561 Compatible** -- Ships with `py.typed` marker for full type-checking support

## Installation

```bash
pip install wackypod
```

## Quick Start

```python
from wackypod import WackyPod

# Initialize the client with your API key
client = WackyPod(api_key="your_api_key_here")

# Create a podcast episode from a URL
episode = client.episodes.create(
    input_type="url",
    input_source="https://example.com/article",
    preset="standard"
)

print(f"Episode created: {episode.id}")
print(f"Status: {episode.status}")

# Wait for the episode to finish processing
episode = client.episodes.wait_for_completion(episode.id)

print(f"Title: {episode.title}")
print(f"Audio URL: {episode.audio_url}")
print(f"Duration: {episode.audio_duration_seconds}s")
```

### Create a multi-host episode from text

```python
episode = client.episodes.create(
    input_type="text",
    input_source="Your article or essay text here...",
    preset="deep",
    host_mode="multi",
    voice_pair="expert-curious"
)

episode = client.episodes.wait_for_completion(episode.id, timeout=900)
```

### Manage webhooks

```python
# Register a webhook for episode events
webhook = client.webhooks.create(
    url="https://example.com/webhook",
    events=["episode.completed", "episode.failed"],
    description="Production notifications"
)

# Save the secret for signature verification
print(f"Webhook secret: {webhook.secret}")
```

### Check account quota

```python
user = client.users.get_profile()
print(f"Plan: {user.tier}")

quota = client.users.get_quota()
print(f"Episodes used: {quota['episodes_used']}/{quota['episodes_limit']}")
```

## API Reference

### Client

```python
client = WackyPod(
    api_key="your_api_key",                      # Required
    base_url="https://api.wackypod.com",         # Optional -- custom API endpoint
    timeout=30                                    # Optional -- request timeout in seconds
)
```

Get your API key at [wackypod.com/settings/api](https://wackypod.com/settings/api).

### Episodes

| Method | Description |
|--------|-------------|
| `client.episodes.create(...)` | Create a new podcast episode |
| `client.episodes.get(episode_id)` | Retrieve an episode by ID |
| `client.episodes.list(status=None, limit=50)` | List episodes with optional filters |
| `client.episodes.delete(episode_id)` | Delete an episode |
| `client.episodes.wait_for_completion(episode_id, timeout=600, poll_interval=5)` | Poll until episode is ready |

**Episode presets:** `quick` (1-3 min), `standard` (5-8 min), `deep` (10-15 min), `extended` (20-30 min)

**Host modes:** `single` (narrated), `multi` (conversational dialogue)

### Webhooks

| Method | Description |
|--------|-------------|
| `client.webhooks.create(url, events, description=None)` | Register a new webhook endpoint |
| `client.webhooks.get(webhook_id)` | Retrieve a webhook by ID |
| `client.webhooks.list()` | List all webhooks |
| `client.webhooks.update(webhook_id, ...)` | Update webhook configuration |
| `client.webhooks.delete(webhook_id)` | Delete a webhook |
| `client.webhooks.test(webhook_id)` | Send a test event |
| `client.webhooks.get_deliveries(webhook_id)` | View delivery history |

**Webhook events:** `episode.completed`, `episode.failed`, `episode.processing`

### Users

| Method | Description |
|--------|-------------|
| `client.users.get_profile()` | Get current user profile |
| `client.users.get_quota()` | Get monthly quota usage |

### Error Handling

All exceptions inherit from `WackyPodError` for convenient catch-all handling:

```python
from wackypod import (
    WackyPodError,         # Base exception
    AuthenticationError,   # Invalid API key (401)
    ValidationError,       # Bad request data (400)
    NotFoundError,         # Resource not found (404)
    RateLimitError,        # Rate limit exceeded (429)
    ServerError,           # Server error (5xx)
)

try:
    episode = client.episodes.create(
        input_type="url",
        input_source="https://example.com/article"
    )
except AuthenticationError:
    print("Check your API key")
except RateLimitError:
    print("Slow down -- rate limit exceeded")
except WackyPodError as e:
    print(f"API error: {e}")
```

## Requirements

- Python 3.8+
- [requests](https://pypi.org/project/requests/) >= 2.28.0

## Development

```bash
git clone https://github.com/ferax564/wackypod-python.git
cd wackypod-python
pip install -e ".[dev]"

# Run tests
pytest

# Format code
black wackypod/

# Type checking
mypy wackypod/
```

## Documentation

Full API documentation is available at [docs.wackypod.com](https://docs.wackypod.com).

## License

MIT License -- see [LICENSE](LICENSE) for details.
