Metadata-Version: 2.4
Name: herosms
Version: 0.1.0
Summary: Async Python client for HeroSMS (sms-activate.ru compatible) API
License: MIT
Keywords: async,herosms,otp,sms,sms-activate
Requires-Python: >=3.10
Requires-Dist: httpx>=0.27.0
Requires-Dist: pydantic>=2.0.0
Requires-Dist: tenacity>=8.0.0
Provides-Extra: dev
Requires-Dist: mypy>=1.10.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
Requires-Dist: pytest-httpx>=0.30.0; extra == 'dev'
Requires-Dist: pytest>=8.0.0; extra == 'dev'
Requires-Dist: ruff>=0.4.0; extra == 'dev'
Description-Content-Type: text/markdown

# herosms

Async and sync Python client for HeroSMS (SMS-Activate compatible API).

## Features

- Async-first client with context-manager support
- Synchronous wrapper for non-async projects
- Activation lifecycle helpers (create, wait, resend, complete, cancel)
- Rent APIs support
- Reference data helpers (countries, services, operators, prices)
- Typed models with Pydantic v2
- Custom exception hierarchy
- Webhook payload parsing for incoming SMS events

## Installation

```bash
pip install herosms
```

For development:

```bash
uv sync --extra dev
```

## Quickstart (async)

```python
import asyncio

from herosms import HeroSMSClient


async def main() -> None:
    async with HeroSMSClient(api_key="YOUR_API_KEY") as client:
        balance = await client.get_balance()
        print(f"Balance: {balance}")

        async with await client.activations.create(service="tg", country=6) as activation:
            status = await activation.wait_for_sms(timeout=120)
            print("Code:", status.code)
            await activation.complete()


asyncio.run(main())
```

## Quickstart (sync)

```python
from herosms import SyncHeroSMSClient


with SyncHeroSMSClient(api_key="YOUR_API_KEY") as client:
    balance = client.get_balance()
    print(f"Balance: {balance}")
```

## Activation lifecycle

Create activation and wait for code:

```python
async with await client.activations.create(service="tg", country=6) as activation:
    status = await activation.wait_for_sms(timeout=120)
    print(status.code)
```

Request another SMS:

```python
await activation.request_sms()
```

Complete or cancel:

```python
await activation.complete()
# or
await activation.cancel()
```

Get all OTP messages for activation:

```python
messages = await activation.get_all_sms()
```

## Legacy status endpoint (`getStatus`)

Use `get_status_v1` if you need raw text-compatible status values from legacy integrations:

```python
raw_status = await client.get_status_v1(activation_id=123456)
print(raw_status)  # e.g. STATUS_WAIT_CODE or STATUS_OK:1234
```

Sync variant:

```python
raw_status = client.get_status_v1(activation_id=123456)
```

## Rent flow

Check availability:

```python
availability = await client.get_rent_availability(service="tg", country=6)
print(availability)
```

Rent a number:

```python
rent_activation = await client.rent_number(service="tg", country=6, duration=2)
print(rent_activation.phone)
```

Sync variants are available with the same method names.

## Reference data APIs

```python
countries = await client.get_countries()
services = await client.get_services(country=6)
operators = await client.get_operators(country=6)
prices = await client.get_prices(service="tg", country=6)
top = await client.get_top_countries(service="tg", by_rank=True)
```

## Error handling

All library exceptions inherit from `HeroSMSError`.

```python
from herosms import HeroSMSError


try:
    ...
except HeroSMSError as exc:
    print(f"HeroSMS error: {exc}")
```

## Webhook payload parsing (`smsIncoming`)

Parse and validate incoming webhook payload with Pydantic model:

```python
from herosms import WebhookSMSIncoming

payload = {
    "activationId": "635468024",
    "service": "tg",
    "text": "Telegram code 123456",
    "code": "123456",
    "country": 6,
    "receivedAt": "2026-02-16T12:36:59+03:00",
}

event = WebhookSMSIncoming.model_validate(payload)
print(event.activation_id, event.code)
```

## API compatibility note

HeroSMS is compatible with SMS-Activate-style API actions. This library targets HeroSMS endpoints while preserving familiar SMS-Activate action semantics.
