# Python SDK

The official server-side Python SDK. The API mirrors `mixpanel-python`, so migrating existing code is mostly a matter of swapping the import and pointing at your Cohorly server. Python 3.8+, zero runtime dependencies, fully typed.

## Install

```bash
pip install cohorly
```

## Initialize

```python
from cohorly import Cohorly

ch = Cohorly("YOUR_PROJECT_TOKEN", api_host="https://cohorly-service.velloalabs.com")

# Track an event (distinct_id passed per call, server-side style)
ch.track("user-1", "Signed Up", {"plan": "pro", "source": "landing"})

# Link an alias to an existing distinct_id
ch.alias("user-1", "anon-7f3a")

# Update a user profile
ch.people_set("user-1", {"$first_name": "Ada", "plan": "pro"})
```

## API

| Member                                                                           | Notes                                                                                                                      |
| -------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| `Cohorly(token, api_host=..., consumer=None)`                                    | Main class. Optionally pass a shared consumer (the token travels per-message, so one consumer can serve several projects). |
| `track(distinct_id, event, properties=None)`                                     | Stamps `time` (unix ms), `$insert_id`, `$lib`, `$lib_version`; your properties win (e.g. custom `$insert_id` for dedup).   |
| `import_data(distinct_id, event, timestamp_ms, props)`                           | Historical events with an explicit timestamp. Same /track pipeline - no separate secret or 5-day cutoff.                   |
| `people_set / people_set_once / people_increment / people_unset / people_delete` | Profile updates mapped to /engage ops.                                                                                     |
| `alias(alias_id, original)`                                                      | POST /alias.                                                                                                               |

## Consumers

By default every call sends immediately via the synchronous
`Consumer` (bounded inline retries). For higher throughput
use `BufferedConsumer`, which batches messages (default 50
per request, server max 500) and implements the shared Cohorly retry
contract - exponential backoff honoring `Retry-After`,
batch halving on 413, permanent drop on 400, queue capped at 1000.

```python
from cohorly import Cohorly, BufferedConsumer

consumer = BufferedConsumer(max_size=50, api_host="https://cohorly-service.velloalabs.com")
ch = Cohorly("YOUR_PROJECT_TOKEN", consumer=consumer)

for user in users:
    ch.track(user.id, "Backfill Event", {"batch": True})

consumer.flush()  # IMPORTANT: drain remaining messages before exit
```

Delivery failures raise `cohorly.CohorlyException`.
`datetime` values serialize to ISO-8601 automatically.
