Metadata-Version: 2.4
Name: truxl
Version: 0.1.0
Summary: Truxl Analytics Python SDK — lightweight, zero-dependency server-side event tracking
Author-email: Truxl <support@truxl.io>
License-Expression: MIT
Project-URL: Homepage, https://truxl.com
Project-URL: Documentation, https://docs.truxl.com/sdk/python
Project-URL: Repository, https://github.com/truxl/truxl-python
Project-URL: Issues, https://github.com/truxl/truxl-python/issues
Keywords: analytics,events,tracking,truxl
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
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 :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.8
Description-Content-Type: text/markdown

# Truxl Python SDK

Lightweight, zero-dependency Python SDK for [Truxl](https://truxl.com) server-side event tracking. Works with Python 3.8+ using only the standard library.

## Installation

```bash
pip install truxl
```

## Quick Start

```python
from truxl import Truxl

truxl = Truxl(
    project_token="trxl_proj_demo_123",
    client_secret="your-client-secret",          # optional, enables HMAC signing
    api_endpoint="https://ingest.truxl.com",      # default
)

# Track a custom event
truxl.track(
    event_name="purchase",
    distinct_id="user-42",
    properties={"price": 29.99, "currency": "USD"},
)

# Identify a user with traits
truxl.identify("user-42", traits={"email": "user@example.com", "plan": "pro"})

# Create an alias
truxl.alias(new_id="user-42", original_id="anon-abc123")

# Force-flush all queued events
truxl.flush()

# Graceful shutdown (blocks until queue drains)
truxl.shutdown()
```

## API Reference

### `Truxl(project_token, ...)`

Create a new client. The background consumer thread starts automatically.

| Parameter | Type | Default | Description |
|---|---|---|---|
| `project_token` | `str` | *required* | Project token for the Truxl ingestion API |
| `client_secret` | `str` | `""` | Secret for HMAC-SHA256 request signing |
| `api_endpoint` | `str` | `"https://ingest.truxl.com"` | Ingestion service base URL |
| `batch_size` | `int` | `20` | Max events per batch request |
| `flush_interval` | `float` | `5.0` | Seconds between automatic flushes |
| `max_queue_size` | `int` | `10000` | Max queued events before dropping |
| `retry_attempts` | `int` | `5` | Retries on 5xx / network errors |
| `retry_base_delay` | `float` | `1.0` | Base delay for exponential backoff |
| `timeout` | `int` | `10` | HTTP request timeout in seconds |

### `truxl.track(event_name, distinct_id=None, properties=None, session_id=None, timestamp=None)`

Track a custom event. `event_name` is required.

- `timestamp` is epoch milliseconds (int). Defaults to the current time.
- `properties` is an arbitrary dict attached to the event.

### `truxl.identify(distinct_id, traits=None)`

Identify a user. Sends a `$identify` event with `properties.$set` containing the traits dict.

### `truxl.alias(new_id, original_id)`

Link two user identities. Sends a `$alias` event.

### `truxl.flush()`

Signal the background thread to flush immediately. Non-blocking.

### `truxl.shutdown(timeout=10.0)`

Shut down the client gracefully. Blocks until the consumer thread finishes or `timeout` seconds elapse. Any remaining events are flushed synchronously after the thread exits.

Always call `shutdown()` before your process exits to avoid losing events.

## Configuration via `TruxlConfig`

For advanced use, you can import and inspect the config object:

```python
from truxl import TruxlConfig

config = TruxlConfig(
    project_token="trxl_proj_demo_123",
    client_secret="your-secret",
    batch_size=50,
    flush_interval=2.0,
)
```

## How It Works

1. `track()`, `identify()`, and `alias()` enqueue events into a thread-safe, bounded queue.
2. A daemon thread wakes every `flush_interval` seconds (or when `batch_size` is reached) and sends batches to the ingestion API.
3. HTTP requests include the `X-Project-Token` header and, when a `client_secret` is configured, an `X-Signature` HMAC-SHA256 header.
4. 5xx and network errors are retried with exponential backoff. 4xx errors are dropped immediately.
5. `shutdown()` signals the thread to exit, waits for it to join, then drains any remaining events synchronously.

## Logging

The SDK logs to the `truxl` logger. To see debug output:

```python
import logging
logging.getLogger("truxl").setLevel(logging.DEBUG)
```

## License

MIT
