> ## Documentation Index
> Fetch the complete documentation index at: https://docs.trysiren.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Python

This is the official Python SDK for the Siren notification platform.

## Installation

```bash theme={null}
pip install trysiren
```

## Basic Usage

### Synchronous Client

```python theme={null}
from siren import SirenClient

# Uses SIREN_API_KEY and SIREN_ENV environment variables
client = SirenClient()

# Send a direct message without template
message_id = client.message.send(
    recipient_value="alice@company.com",
    channel="EMAIL",
    body="Your account has been successfully verified. You can now access all features."
)

# Send a message using a template
message_id = client.message.send(
    recipient_value="U01UBCD06BB",
    channel="SLACK",
    template_name="welcome_template",
    template_variables={"user_name": "John"},
)

# Send a message with specific provider
from siren.models.messaging import ProviderCode
message_id = client.message.send(
    recipient_value="alice@company.com",
    channel="EMAIL",
    body="Your account has been successfully verified.",
    provider_name="email-provider",
    provider_code=ProviderCode.EMAIL_SENDGRID,
)

# Send a message using awesome template
message_id = client.message.send_awesome_template(
    recipient_value="U01UBCD06BB",
    channel="SLACK",
    template_identifier="awesome-templates/customer-support/escalation_required/official/casual.yaml",
    template_variables={
        "ticket_id": "123456",
        "customer_name": "John",
        "issue_summary": "Payment processing issue",
        "ticket_url": "https://support.company.com/ticket/123456",
        "sender_name": "Support Team"
    },
    provider_name="slack-provider",
    provider_code=ProviderCode.SLACK,
)

# Alternative initialization
client = SirenClient(api_key="YOUR_SIREN_API_KEY")  # default env is "prod"
# Or:
client = SirenClient(api_key="YOUR_SIREN_API_KEY", env="dev")
```

### Asynchronous Client

```python theme={null}
from siren import AsyncSirenClient

# Using async context manager (recommended)
async with AsyncSirenClient() as client:
    message_id = await client.message.send(
        recipient_value="alice@company.com",
        channel="EMAIL",
        body="Your account has been successfully verified. You can now access all features."
    )

# Or manually managing the client
client = AsyncSirenClient()
try:
    message_id = await client.message.send(
        recipient_value="alice@company.com",
        channel="EMAIL",
        body="Your account has been successfully verified. You can now access all features."
    )
finally:
    await client.aclose()
```

All synchronous methods have a 1-to-1 asynchronous equivalent—just await them on the async client.

## SDK Methods

The Siren Python SDK provides a clean, namespaced interface to interact with the Siren API. Below are the available methods organized by functionality.

### Templates

| Method                      | Description                                                                                 |
| --------------------------- | ------------------------------------------------------------------------------------------- |
| `client.template.get()`     | Retrieves a list of notification templates with optional filtering, sorting, and pagination |
| `client.template.create()`  | Creates a new notification template                                                         |
| `client.template.update()`  | Updates an existing notification template                                                   |
| `client.template.delete()`  | Deletes an existing notification template                                                   |
| `client.template.publish()` | Publishes a template, making its latest draft version live                                  |

### Channel Templates

| Method                             | Description                                                      |
| ---------------------------------- | ---------------------------------------------------------------- |
| `client.channel_template.create()` | Creates or updates channel-specific templates (EMAIL, SMS, etc.) |
| `client.channel_template.get()`    | Retrieves channel templates for a specific template version      |

### Messaging

| Method                                   | Description                                                                      |
| ---------------------------------------- | -------------------------------------------------------------------------------- |
| `client.message.send()`                  | Sends a message (with or without a template) to a recipient via a chosen channel |
| `client.message.send_awesome_template()` | Sends a message using a template path/identifier                                 |
| `client.message.get_replies()`           | Retrieves replies for a specific message ID                                      |
| `client.message.get_status()`            | Retrieves the status of a specific message (SENT, DELIVERED, FAILED, etc.)       |

### Workflows

| Method                           | Description                                                      |
| -------------------------------- | ---------------------------------------------------------------- |
| `client.workflow.trigger()`      | Triggers a workflow with given data and notification payloads    |
| `client.workflow.trigger_bulk()` | Triggers a workflow in bulk for multiple recipients              |
| `client.workflow.schedule()`     | Schedules a workflow to run at a future time (once or recurring) |

### Webhooks

| Method                                     | Description                                           |
| ------------------------------------------ | ----------------------------------------------------- |
| `client.webhook.configure_notifications()` | Configures webhook URL for receiving status updates   |
| `client.webhook.configure_inbound()`       | Configures webhook URL for receiving inbound messages |

### Users

| Method                 | Description                                                       |
| ---------------------- | ----------------------------------------------------------------- |
| `client.user.add()`    | Creates a new user or updates existing user with given unique\_id |
| `client.user.update()` | Updates an existing user's information                            |
| `client.user.delete()` | Deletes an existing user                                          |

## For Package Developers

### Environment Configuration

For testing the SDK, set these environment variables:

* `SIREN_API_KEY`: Your API key from the Siren dashboard
* `SIREN_ENV`: Set to `dev` for development/testing (defaults to `prod`)

### Prerequisites

* Git
* Python 3.8 or higher
* uv (installed, see [uv installation guide](https://github.com/astral-sh/uv))

### Setup Steps

1. **Clone the repository**:
   ```bash theme={null}
   git clone https://github.com/KeyValueSoftwareSystems/siren-py-sdk.git
   cd siren-py-sdk
   ```

2. **Create a virtual environment using uv**:
   ```bash theme={null}
   uv venv
   ```

3. **Activate the virtual environment**:
   ```bash theme={null}
   # On macOS/Linux
   source .venv/bin/activate
   # On Windows
   .venv\Scripts\activate
   ```

4. **Install dependencies with uv**:
   ```bash theme={null}
   uv pip install -e ".[dev]"
   ```

5. **Set up pre-commit hooks**:
   ```bash theme={null}
   uv run pre-commit install
   ```

You are now ready to contribute to the trysiren SDK!

### Code Style & Linting

Code style is enforced by:

* `ruff` (linting, formatting, import sorting)
* `pyright` (type checking)

These tools are automatically run via pre-commit hooks.

### Running Tests

To run the test suite, use the following command from the project root directory:

```bash theme={null}
uv run pytest
```

This will execute all tests defined in the `tests/` directory.

### Submitting Changes

1. Create a feature branch for your changes
2. Commit your changes (pre-commit hooks will run)
3. Push your branch and open a Pull Request against the `develop` branch

### Changes Planned

* Investigate how critical `.close()` is for async client
* Explore ways to avoid manual `.close()` calls
