Skip to main content

Асинхронный клиент для DesslyHub API (Steam, мобильные игры, ваучеры, eSIM, заказы, баланс, курсы валют)

Project description

DesslyHub API

desslyhub-api

Асинхронный Python-клиент для DesslyHub API:
Steam, мобильные игры, ваучеры, eSIM, баланс мерчанта, заказы и курсы валют.

Python 3.12+ MIT black mypy aiohttp + orjson


Клиент построен на aiohttp + orjson, ответы валидируются через pydantic, денежные значения представлены типом Decimal. Все эндпоинты доступны под базовым URL https://desslyhub.com с префиксом /api/v1/.

Содержание

Возможности

Ресурс Назначение
client.steam Каталог игр для подарка, издания игры и проверка логина для пополнения.
client.mobile Каталог мобильных игр и детали конкретной игры.
client.vouchers Каталог товаров-ваучеров и товар по идентификатору.
client.esim Каталог вариантов eSIM с курсорной пагинацией и детали варианта.
client.merchant Текущий баланс мерчанта.
client.exchange Курсы валют к доллару США для пополнения Steam.
client.orders Единая точка создания всех покупок (пополнения, подарки, ваучеры, eSIM), а также список и детали заказов.

Создание любых покупок выполняется через ресурс orders (единый эндпоинт POST /api/v1/orders). Прежние методы gift / top_up / refill / buy и ресурс merchants с эндпоинтами /transactions удалены — историю и статусы покупок заменили заказы.

Установка

Требования: Python 3.12+ и uv.

Для конечных пользователей

uv add desslyhub-api
# или
pip install desslyhub-api

Импорт пакета: import desslyhub_api.

Для локальной разработки

Клонируйте репозиторий и установите все группы зависимостей (включая dev-инструменты: pytest, black, isort, mypy):

uv sync --all-groups

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

import asyncio

from desslyhub_api import DesslyHubClient


async def main() -> None:
    async with DesslyHubClient("ВАШ_API_КЛЮЧ", "ВАШ_SECRET") as client:
        balance = await client.merchant.get_balance()
        print(balance.balance)  # Decimal


asyncio.run(main())

Клиент — асинхронный контекстный менеджер: внутри async with открывается постоянная HTTP-сессия, которая автоматически закрывается на выходе.

Аутентификация

Каждый запрос подписывается по схеме HMAC-SHA256: signature = HMAC_SHA256(secret, api_key + timestamp + body). Клиент сам добавляет к каждому запросу заголовки X-Api-Key, X-Timestamp (Unix-время в секундах) и X-Signature. Поэтому нужны два значения — api_key и secret. Базовый URL по умолчанию — https://desslyhub.com.

from desslyhub_api import DesslyHubClient

# Минимальный вариант
client = DesslyHubClient("ВАШ_API_КЛЮЧ", "ВАШ_SECRET")

# С переопределением base_url и таймаута
client = DesslyHubClient(
    "ВАШ_API_КЛЮЧ",
    "ВАШ_SECRET",
    base_url="https://desslyhub.com",
    timeout_seconds=30.0,
)

Использование

Все методы асинхронные и вызываются внутри async with DesslyHubClient(api_key, secret) as client:.

Баланс мерчанта

balance = await client.merchant.get_balance()
print(balance.balance)            # Decimal — общий баланс
print(balance.available_balance)  # Decimal — доступно для трат
print(balance.overdraft)          # Decimal — лимит овердрафта
print(balance.reserve)            # Decimal — зарезервированные средства

get_balance() возвращает модель Balance с полями balance, available_balance, overdraft, reserve — все значения типа Decimal.

Steam: каталог игр, издания и проверка логина

games = await client.steam.get_games()
for game in games:
    print(game)

# Издания конкретной игры по её app_id
editions = await client.steam.get_editions(app_id=730)
for edition in editions:
    print(edition)

# Можно ли пополнить аккаунт Steam с указанным логином
can_refill = await client.steam.check_login(username="steam_user")
print(can_refill)  # bool

Mobile: каталог и детали игры

games = await client.mobile.get_games()
for game in games:
    print(game)

details = await client.mobile.get_game(game_id=42)
print(details)

Vouchers: каталог

products = await client.vouchers.get_products()
for product in products:
    print(product)

product = await client.vouchers.get_product(product_id=10)
print(product)

eSIM: каталог

page = await client.esim.get_products()  # cursor=None — первая страница
for variant in page.variants:
    print(variant)

# Следующая страница по курсору
if page.next_cursor:
    next_page = await client.esim.get_products(cursor=page.next_cursor)
    print(next_page.variants)

details = await client.esim.get_product(variant_id="variant-123")
print(details)

Exchange: курсы валют

from desslyhub_api import Currency

all_rates = await client.exchange.get_all_rates()
print(all_rates.rates)  # dict[int, float]

# Курс по конкретной валюте (enum Currency или числовой код)
rate = await client.exchange.get_rate(Currency.RUB)
print(rate.rate)

Заказы (Orders)

Все покупки создаются через ресурс client.orders. Каждый метод create_* возвращает CreateOrderResponse с полями order_id (int) и status (str). Типичный сценарий:

  1. Создать заказ методом create_* — в ответе придут order_id и status.
  2. Опрашивать заказ через client.orders.get(order_id), отслеживая order_status и service_result (результат становится доступен после успешного выполнения).

У всех методов create_* есть общие необязательные параметры (только по ключу):

  • payment_method: PaymentMethod — способ оплаты, по умолчанию PaymentMethod.BALANCE (списание с баланса мерчанта). Для оплаты по QR-ссылке — PaymentMethod.PAYLINK_QR.
  • payment_params: PaylinkQRPaymentParams | None — параметры оплаты по QR (нужны для PAYLINK_QR).
  • reference: str | None — ваш внешний идентификатор заказа.

Оплата с баланса (по умолчанию)

# Пополнение Steam
order = await client.orders.create_steam_refill(
    username="steam_user",
    amount=10.0,                 # сумма в USD
    reference="my-order-id",     # необязательно
)
print(order.order_id, order.status)

# Подарок игры Steam
order = await client.orders.create_steam_gift(
    invite_url="https://steamcommunity.com/p/...",
    package_id="12345",
    region="RU",
)

# Покупка ваучеров
order = await client.orders.create_voucher(
    root_id=10,
    variant_id=2,
    quantity=1,
)

# Пополнение мобильной игры
order = await client.orders.create_mobile_refill(
    position=3,
    fields={"player_id": "123456"},
)

# Покупка eSIM
order = await client.orders.create_esim(
    product_id="product-123",
    variant_id="variant-456",
)

Оплата по QR-ссылке (PAYLINK_QR)

from desslyhub_api import PaymentMethod, PaylinkQRPaymentParams

order = await client.orders.create_steam_refill(
    username="steam_user",
    amount=10.0,
    payment_method=PaymentMethod.PAYLINK_QR,
    payment_params=PaylinkQRPaymentParams(
        amount=1000,
        success_url="https://example.com/success",
        fail_url="https://example.com/fail",
    ),
    reference="my-order-id",
)
print(order.order_id, order.status)

Список и детали заказов

# Страница списка с пагинацией limit/offset
page = await client.orders.list(limit=20, offset=0)
print(page.total, page.limit, page.offset)
for item in page.items:
    print(item.order_id, item.order_status)

# Подробности конкретного заказа
details = await client.orders.get(order_id=12345)
print(details.order_status)    # str — статус заказа
print(details.service_type)    # str — тип сервиса
print(details.commission)      # Decimal — комиссия
print(details.final_amount)    # Decimal — итоговая сумма
print(details.service_result)  # результат выполнения (после успеха)

list() возвращает OrderList с полями items, total, limit, offset. get() возвращает OrderDetails с полями order_id, order_status, service_type, payment_method, commission и final_amount (оба Decimal), временными метками и service_result.

Денежные значения и обработка ошибок

  • Денежные значения (например поля Balance, а также commission и final_amount в OrderDetails) представлены типом Decimal, чтобы избежать ошибок округления.
  • При HTTP-статусе ответа >= 400 клиент бросает DesslyHubAPIError. Тело ошибки разбирается в формате RFC 7807 (ErrorModel). У исключения есть атрибуты error_code (int), message (str) и http_status (int | None).
  • Сетевые проблемы поднимают DesslyHubConnectionError.
  • Некорректный/нечитаемый ответ API поднимает DesslyHubResponseError.
  • Все исключения наследуются от базового DesslyHubError.
from desslyhub_api import (
    DesslyHubAPIError,
    DesslyHubConnectionError,
    DesslyHubResponseError,
)

async with DesslyHubClient(api_key, secret) as client:
    try:
        balance = await client.merchant.get_balance()
    except DesslyHubAPIError as error:
        print("Ошибка API:", error.error_code, error.message, error.http_status)
    except DesslyHubConnectionError as error:
        print("Ошибка соединения:", error)
    except DesslyHubResponseError as error:
        print("Некорректный ответ:", error)

Разработка

Установка окружения со всеми dev-зависимостями (pytest, black, isort, mypy):

uv sync --all-groups

Полезные команды:

uv run pytest -q                   # тесты
uv run isort . && uv run black .   # форматирование
uv run mypy desslyhub_api          # проверка типов

Лицензия

MIT.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

desslyhub_api-0.1.0.tar.gz (98.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

desslyhub_api-0.1.0-py3-none-any.whl (27.5 kB view details)

Uploaded Python 3

File details

Details for the file desslyhub_api-0.1.0.tar.gz.

File metadata

  • Download URL: desslyhub_api-0.1.0.tar.gz
  • Upload date:
  • Size: 98.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.10 {"installer":{"name":"uv","version":"0.10.10","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for desslyhub_api-0.1.0.tar.gz
Algorithm Hash digest
SHA256 4ee7f6872971b6358c9565cd7268c1fd7b7eceb9437f1cafd6b8a7b25c7eea78
MD5 8b2b19d177b063380c96734be3477ffd
BLAKE2b-256 4607a74ec5815b6d6c07cd4ca2e22537d42b31fcc55cca11b3afb4b5764b5ca8

See more details on using hashes here.

File details

Details for the file desslyhub_api-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: desslyhub_api-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 27.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.10 {"installer":{"name":"uv","version":"0.10.10","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for desslyhub_api-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 93f6ba95b9f8a4fc2767274cfb2f4401fcb9c21b9e7f0ed44491a2c4af2eede5
MD5 b15d4f089738416e2bfb67e59077f6e7
BLAKE2b-256 d34147cd014d81af1324fd9ac2bd618e8e86682315c89e3776302cd0f745e79e

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page