Metadata-Version: 2.4
Name: sf-queue-sdk
Version: 0.1.0b15
Summary: Python SDK for sf-queue - Redis-based queue system
Requires-Python: >=3.11
Requires-Dist: redis>=5.0.0
Description-Content-Type: text/markdown

# sf-queue-sdk

Python SDK for sf-queue. Enqueues emails via Redis Streams with optional blocking confirmation from the Go consumer service.

## Installation

```bash
pip install sf-queue-sdk
```

## Setup

```python
from queue_sdk import QueueClient

client = QueueClient(
    redis_url="redis://localhost:6379",
    redis_password="your-password",
    environment="staging",  # prefixes stream names: staging:{email}
)
```

## Single Email

### Fire and forget

Enqueues the email and returns immediately. Does not wait for the consumer to process it.

```python
result = client.email.send(
    to="user@example.com",
    preview="Welcome to StudyFetch!",
    subject="Welcome to StudyFetch!",
    paragraphs=[
        "Hey there,",
        "Welcome to the StudyFetch community!",
        "Thanks for joining us.",
    ],
    button={
        "text": "Go to Platform",
        "href": "https://www.studyfetch.com/platform",
    },
)

print("Enqueued:", result.message_id)
```

### Send and wait for confirmation

Enqueues the email and blocks until the Go consumer processes it (or timeout).

```python
result = client.email.send_and_wait(
    to="user@example.com",
    preview="Reset your password",
    subject="StudyFetch: Reset Your Password",
    paragraphs=[
        "Hi There,",
        "Click the button below to reset your password.",
    ],
    button={
        "text": "Reset Password",
        "href": "https://www.studyfetch.com/reset?token=abc",
    },
    timeout=30,  # optional, default 30s
)

print(result.success)     # True or False
print(result.message_id)  # request ID
print(result.error)       # error message if failed
```

## Batch Email

Send the same email content to multiple recipients (up to 100). The Go consumer sends to each recipient individually.

### Fire and forget

```python
result = client.email.send_batch(
    to=[
        "student1@example.com",
        "student2@example.com",
        "student3@example.com",
    ],
    preview="You have been invited to join a class!",
    subject="StudyFetch: Class Invitation",
    paragraphs=[
        "Hi There,",
        'You have been invited to join "Intro to CS" on StudyFetch!',
        "Click the button below to accept the invite.",
    ],
    button={
        "text": "Accept Invite",
        "href": "https://www.studyfetch.com/invite/abc",
    },
)

print("Enqueued:", result.message_id)
```

### Send and wait for confirmation

```python
result = client.email.send_batch_and_wait(
    to=[
        "student1@example.com",
        "student2@example.com",
        "student3@example.com",
    ],
    preview="You have been invited to join a class!",
    subject="StudyFetch: Class Invitation",
    paragraphs=[
        "Hi There,",
        'You have been invited to join "Intro to CS" on StudyFetch!',
        "Click the button below to accept the invite.",
    ],
    button={
        "text": "Accept Invite",
        "href": "https://www.studyfetch.com/invite/abc",
    },
    timeout=30,
)

print(result.success)     # True if at least some sent
print(result.message_id)  # request ID
print(result.total)       # 3
print(result.successful)  # number sent successfully
print(result.failed)      # number that failed
print(result.error)       # error message if all failed
```

## All Email Fields

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `to` | `str` | Yes (single) | Recipient email address |
| `to` | `list[str]` | Yes (batch) | List of recipient emails (max 100) |
| `preview` | `str` | Yes | Preview text shown in email clients |
| `subject` | `str` | Yes | Email subject line |
| `paragraphs` | `list[str]` | Yes | Body content as paragraph strings |
| `button` | `{"text": str, "href": str}` | No | Call-to-action button |
| `reply_to` | `str` | No | Reply-to email address |
| `image` | `{"src": str, "alt"?: str, "width"?: int, "height"?: int}` | No | Image in email body |

## Optional Fields

```python
# With all optional fields
client.email.send(
    to="support@studyfetch.com",
    preview="Support Request",
    subject="StudyFetch: Support Request",
    paragraphs=["Hi There,", "You received a support request.", issue],
    reply_to="requester@example.com",
    image={
        "src": "https://example.com/logo.png",
        "alt": "Logo",
        "width": 150,
        "height": 50,
    },
)
```

## Migrating from sendEmail / sendBatchEmail

The SDK is a drop-in replacement. Field names match the existing functions:

```python
# BEFORE
send_email(to=to, preview=preview, subject=subject, paragraphs=paragraphs, button=button)

# AFTER (fire and forget)
client.email.send(to=to, preview=preview, subject=subject, paragraphs=paragraphs, button=button)

# AFTER (wait for confirmation)
client.email.send_and_wait(to=to, preview=preview, subject=subject, paragraphs=paragraphs, button=button)

# BEFORE (batch)
send_batch_email(to=[...], preview=preview, subject=subject, paragraphs=paragraphs, button=button)

# AFTER (batch, fire and forget)
client.email.send_batch(to=[...], preview=preview, subject=subject, paragraphs=paragraphs, button=button)

# AFTER (batch, wait for confirmation)
client.email.send_batch_and_wait(to=[...], preview=preview, subject=subject, paragraphs=paragraphs, button=button)
```

## Methods and Response Types

| Method | Return Type | Fields |
|--------|-------------|--------|
| `send()` | `SendResult` | `message_id` |
| `send_and_wait()` | `EmailResponse` | `success`, `message_id`, `error?`, `processed_at?` |
| `send_batch()` | `SendResult` | `message_id` |
| `send_batch_and_wait()` | `BatchEmailResponse` | `success`, `message_id`, `error?`, `processed_at?`, `total`, `successful`, `failed` |

## Cleanup

```python
client.disconnect()
```
