Metadata-Version: 2.4
Name: weplaytestgames
Version: 0.1.0
Summary: Official Python SDK for the We Playtest Games API
License-Expression: MIT
License-File: LICENSE
Requires-Python: >=3.9
Requires-Dist: httpx<1.0.0,>=0.25.0
Requires-Dist: typing-extensions>=4.0
Provides-Extra: dev
Requires-Dist: psycopg2-binary>=2.9; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest>=7.0; extra == 'dev'
Requires-Dist: respx>=0.21; extra == 'dev'
Description-Content-Type: text/markdown

# We Playtest Games - Python SDK

Official Python SDK for the [We Playtest Games](https://weplaytestgames.com) API.

## Installation

```bash
pip install weplaytestgames
```

## Quickstart

### Synchronous

```python
from weplaytestgames import WPGClient

with WPGClient(api_key="wpg_sk_...") as client:
    # List your games
    page = client.games.list().get_page()
    print(page.data)

    # Create a game
    game = client.games.create(
        name="My Game",
        build_url="https://store.steampowered.com/app/123456",
    )

    # Order playtests
    result = client.playtests.create(
        game_id=game["id"],
        visibility="public",
        quantity=3,
        duration_minutes=60,
    )
```

### Async

```python
from weplaytestgames import AsyncWPGClient

async with AsyncWPGClient(api_key="wpg_sk_...") as client:
    page = await client.games.list().get_page()
    game = await client.games.create(name="My Game", build_url="https://example.com")
```

## Authentication

Get an API key from your [dashboard](https://app.weplaytestgames.com) or register programmatically:

```python
result = WPGClient.register_with_api_key(
    email="studio@example.com",
    password="securepassword",
    company_name="My Studio",
)
api_key = result["api_key"]
```

## Features

- **TypedDict responses** - All responses use typed dictionaries with snake_case keys
- **Sync and async** - `WPGClient` for synchronous code, `AsyncWPGClient` for async
- **Pagination** - Cursor-based pagination with `get_page()` and `get_all()` helpers
- **Retry with backoff** - Automatic retries on 429/5xx errors with exponential backoff (configurable via `max_retries`)
- **Webhook verification** - `verify_webhook_signature()` with replay protection
- **Idempotency** - Pass idempotency keys to mutating operations

## Configuration

```python
client = WPGClient(
    api_key="wpg_sk_...",
    base_url="https://app.weplaytestgames.com/api/v1",  # default
    timeout=30.0,       # seconds, default 30
    max_retries=2,      # default 2 (3 total attempts), 0 to disable
)
```

## Available Resources

| Resource | Methods |
|----------|---------|
| `client.auth` | `me()`, `profile()`, `update_profile()`, `categories()`, `devices()` |
| `client.games` | `list()`, `get()`, `create()`, `update()` |
| `client.playtests` | `list()`, `get()`, `create()`, `update()` |
| `client.slots` | `get()`, `accept()`, `reject()`, `download_url()`, `transcript()` |
| `client.submissions` | `list()`, `get()` |
| `client.billing` | `get_balance()`, `payments()`, `get_payment()`, `purchase_credit()` |
| `client.chat` | `contacts()`, `conversation()`, `send_message()`, `unread_count()` |
| `client.webhooks` | `list()`, `create()`, `update()`, `delete()`, `test()`, `deliveries()` |
| `client.notifications` | `list()`, `mark_read()`, `mark_all_read()` |
| `client.dashboard` | `stats()` |

## Webhook Verification

```python
from weplaytestgames import verify_webhook_signature

is_valid = verify_webhook_signature(
    payload=raw_body,
    signature=request.headers["X-WPG-Signature"],
    timestamp=request.headers["X-WPG-Timestamp"],
    secret=webhook_secret,
)
```

## Documentation

Full API documentation: [weplaytestgames.com/docs](https://weplaytestgames.com/docs)

## License

MIT
