Metadata-Version: 2.4
Name: sova-partner
Version: 0.1.1
Summary: Python SDK для партнёрского API SOVA VPN (ресейл VPN-серверов и конфигов)
Author: SOVA VPN
License: MIT
Project-URL: Homepage, https://partner.sova-vpn.online
Project-URL: Documentation, https://partner.sova-vpn.online
Project-URL: OpenAPI schema, https://api.sova-vpn.online/partner/v1/openapi.json
Keywords: sova,vpn,wireguard,reseller,api,sdk,partner
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Topic :: Internet
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: httpx>=0.24
Dynamic: license-file

# sova-partner

[![PyPI](https://img.shields.io/pypi/v/sova-partner.svg)](https://pypi.org/project/sova-partner/)
[![Python](https://img.shields.io/pypi/pyversions/sova-partner.svg)](https://pypi.org/project/sova-partner/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

Официальный Python SDK партнёрского API **SOVA VPN** — ресейл VPN-серверов и
конфигов (WireGuard, AmneziaWG, VLESS Reality, Trojan, Shadowsocks, OpenVPN,
SOCKS5, Tailscale) через простой типизированный клиент.

- 🖥️ **Серверы**: заказ у провайдера (Inferno/UltaHost, 40+ стран), питание, переустановка, продление.
- 🔑 **Конфиги**: мгновенный выпуск, ротация, отзыв (hard-revoke), метрики.
- 💳 **Биллинг**: баланс, каталог/цены, пополнение (CryptoBot/USDT), лестница скидок.
- 🔔 **Вебхуки**: проверка HMAC-подписи из коробки.
- 🛡️ **Идемпотентность** заказа/выпуска/продления — автоматически.
- 🧩 **Sandbox**: ключ `sova_test_…` — весь флоу без списаний и реальных VPS.

## Установка

```bash
pip install sova-partner
```

Требует Python ≥ 3.8. Единственная зависимость — `httpx`.

## Быстрый старт

```python
from sova_partner import SovaPartner

sova = SovaPartner("sova_live_…")          # sova_test_… — песочница

# цена без покупки
print(sova.quote(pc=10, term_days=30)["prices"])

# заказать сервер и дождаться готовности (выдача 10 мин – 2 ч)
srv = sova.create_server(country="DE", pc=10, term_days=30)   # provider="inferno"/"ultahost" опц.
srv = sova.wait_for_server(srv["server_id"])

# выпустить конфиг — вернётся готовый .conf/URI
cfg = sova.issue_config(srv["server_id"], protocol="wireguard", name="ноутбук")
print(cfg["config"])

sova.rotate_config(cfg["config_id"])        # ротация ключей
sova.revoke_config(cfg["config_id"])        # отзыв (снимает пир на сервере)
sova.renew(srv["server_id"], term_days=30)  # продление
```

`Idempotency-Key` для `create_server` / `issue_config` / `renew` генерируется
автоматически (можно передать свой через `idempotency_key=`).

## Онбординг нового партнёра (без ключа)

```python
from sova_partner import Onboarding

ob = Onboarding()
r = ob.register(name="Моя компания", password="…")     # -> claim_token
ob.deposit(r["claim_token"], amount=50)                # -> pay_url (CryptoBot)
# ob.deposit_usdt(r["claim_token"], amount=50)         # или прямой USDT TRC20
api_key = ob.wait_for_key(r["claim_token"])            # после оплаты -> первый ключ (ОДИН раз!)
```

Первый ключ выдаётся после депозита ≥ min_deposit. Крупный первый депозит даёт
бонус на баланс (≥$300 +5% / ≥$1000 +10% / ≥$3000 +15%) и постоянную скидку.

## Вебхуки — проверка подписи

```python
from sova_partner import verify_signature

ok = verify_signature(
    secret=endpoint_secret,                        # выдан при create_webhook (один раз)
    signature_header=request.headers["X-Sova-Signature"],
    raw_body=request.body,                         # СЫРОЕ тело до JSON-парсинга
)
event    = request.headers["X-Sova-Event"]         # см. список ниже
event_id = request.headers["X-Sova-Event-Id"]      # дедуп (доставка at-least-once)
```

События: `server.ready` · `server.failed` · `server.expiring` ·
`config.created` · `config.revoked` · `config.rotated` · `deposit.paid` · `balance.low`.

## Справочник методов

**`SovaPartner(api_key, base_url=…, timeout=30)`** — клиент по API-ключу:

| Раздел | Методы |
|---|---|
| Аккаунт | `balance()` · `catalog()` · `quote(pc/plan_id, term_days)` · `stats()` · `ledger()` |
| Пополнение¹ | `deposit(amount)` · `deposit_usdt(amount)` · `deposit_usdt_status(id)` |
| Ключи¹ | `list_keys()` · `create_key(mode, scopes, ip_allowlist)` · `revoke_key(id)` |
| Серверы | `create_server(country, pc, …)` · `list_servers()` · `get_server(id)` · `wait_for_server(id)` · `server_metrics(id)` · `server_protocols(id)` · `power(id, action)` · `reinstall(id)` · `renew(id, term_days)` |
| Конфиги | `issue_config(server_id, protocol, …)` · `list_configs(id)` · `get_config(id)` · `rename_config(id, name)` · `rotate_config(id)` · `revoke_config(id)` |
| Вебхуки¹ | `create_webhook(url, events)` · `list_webhooks()` · `delete_webhook(id)` |
| Поддержка¹ | `create_ticket(message, topic, server_id)` · `list_tickets()` |

**`Onboarding(base_url=…)`** — публичный флоу: `register` · `deposit` · `deposit_usdt` · `status` · `wait_for_key`.

¹ требует scope `account:manage` (в дефолтные ключи не входит — используйте вход в ЛК или ключ с этим правом).

## Обработка ошибок

Все не-2xx поднимают исключение с `.status` и `.code` (машинный `detail`):

```python
from sova_partner import SovaError, SovaInsufficientBalance, SovaAuthError, SovaRateLimited

try:
    sova.create_server(country="DE", pc=10)
except SovaInsufficientBalance:      # 402
    ...
except SovaAuthError as e:           # 401/403 (invalid_key / insufficient_scope / ip_not_allowed)
    print(e.code)
except SovaRateLimited:              # 429
    ...
except SovaError as e:               # 409 idempotency_key_reused, 404, …
    print(e.status, e.code)
```

## Права ключа (scopes)

`catalog:read` · `balance:read` · `vpn:read` · `vpn:issue` · `vpn:revoke` · `account:manage`.
Ключ можно ограничить по IP (`ip_allowlist`). Управление ключами/вебхуками/депозитами/тикетами
требует `account:manage`.

## Ссылки

- Документация и коды ошибок: <https://partner.sova-vpn.online> (раздел «Документация API»)
- OpenAPI 3.1 схема: <https://api.sova-vpn.online/partner/v1/openapi.json>
- История изменений: `CHANGELOG.md` в составе пакета

Базовый URL по умолчанию — `https://api.sova-vpn.online/partner/v1` (меняется параметром `base_url`).

MIT © SOVA VPN
