$ sudo teach IT
Модуль 2 · CryptoPay Client

Урок 2.4 — Типы данных и Enum'ы

Изучим все типы данных библиотеки aiosend: от примитивных Enum до сложных Pydantic-моделей. Научимся работать с Asset, Fiat, CurrencyType, InvoiceStatus и сериализацией объектов.

Библиотека aiosend использует строгую систему типов на основе Pydantic. Каждый ответ API, каждый параметр метода — это типизированный объект. Понимание этих типов — ключ к эффективной работе с библиотекой. В этом уроке мы разберём все Enum'ы, модели данных и способы работы с ними.

🏗️

Иерархия типов aiosend

Все типы данных в aiosend можно разделить на три категории:

Категория Типы Описание
Enum (перечисления) Asset, Fiat, CurrencyType, InvoiceStatus, CheckStatus, UpdateType, PaidBtnName Фиксированные наборы значений (строковые enum'ы)
Pydantic модели (CryptoPayObject) App, Invoice, Check, Transfer, Balance, Currency, ExchangeRate, AppStats Типизированные объекты, возвращаемые API
Служебные модели Update, Response, Error, Network Внутренние и вспомогательные типы

🔍 Где находятся типы?

Все типы импортируются напрямую из aiosend: from aiosend import Asset, Fiat, Invoice, App. Либо из подмодуля aiosend.types для более детального импорта. Enum'ы находятся в aiosend.enums.

💰

Enum Asset — криптовалюты

Enum Asset — это перечисление всех криптовалют, поддерживаемых Crypto Pay. Он используется везде, где нужно указать криптовалюту: при создании инвойса, получении курса, проверке баланса.

Значение Enum Строковое значение Описание
Asset.USDT "USDT" Tether (USDT) — стейблкоин, привязанный к доллару США
Asset.TON "TON" Toncoin — нативная криптовалюта блокчейна TON
Asset.BTC "BTC" Bitcoin — первая и самая известная криптовалюта
Asset.ETH "ETH" Ethereum — платформа для смарт-контрактов
Asset.LTC "LTC" Litecoin — «цифровое серебро»
Asset.BNB "BNB" Binance Coin — нативный токен Binance Chain
Asset.TRX "TRX" TRON — протокол для децентрализованных приложений
Asset.USDC "USDC" USD Coin — стейблкоин от Circle
Asset.JET "JET" Тестовый актив для TESTNET (недоступен в MAINNET)
Asset.SEND "SEND" SEND — токен экосистемы Crypto Bot
Asset.SOL "SOL" Solana — высокопроизводительный блокчейн
Asset.XAUT "XAUT" Tether Gold — токенизированное золото
Python · Работа с Asset
from aiosend import Asset

# Доступ к значениям
print(Asset.USDT)        # Asset.USDT
print(Asset.USDT.value)  # "USDT"
print(Asset("TON"))      # Asset.TON (из строки)
print(Asset.BTC.name)    # "BTC" (имя атрибута)

# Итерация по всем активам
for asset in Asset:
    print(f"{asset.name}: {asset.value}")

# Проверка
if some_value in Asset._value2member_map_:
    asset = Asset(some_value)
    print(f"Это актив: {asset}")

# Сравнение
if user_asset == Asset.USDT:
    print("Пользователь выбрал USDT")

⚠️ JET только для TESTNET

Актив JET — тестовый. Он доступен только в TESTNET и используется для разработки и отладки. В MAINNET этот актив недоступен. При попытке создать инвойс в JET на MAINNET ты получишь ошибку API.

💵

Enum Fiat — фиатные валюты

Enum Fiat содержит все фиатные валюты, поддерживаемые Crypto Pay для создания счетов в фиате. Используется в параметре fiat метода create_invoice().

Значение Enum Страна / Описание
Fiat.USD Доллар США (самая популярная фиатная валюта)
Fiat.EUR Евро (зона евро)
Fiat.RUB Российский рубль
Fiat.BYN Белорусский рубль
Fiat.UAH Украинская гривна
Fiat.GBP Британский фунт стерлингов
Fiat.CNY Китайский юань
Fiat.KZT Казахстанский тенге
Fiat.UZS Узбекский сум
Fiat.GEL Грузинский лари
Fiat.TRY Турецкая лира
Fiat.AED Дирхам ОАЭ
Python · Работа с Fiat
from aiosend import Fiat

# Использование
invoice = await cp.create_invoice(
    amount=100,
    fiat=Fiat.USD,     # можно передать сам Enum
    # или просто строку "USD"
)

# Доступ к значению
print(Fiat.EUR.value)    # "EUR"
print(Fiat.RUB.name)     # "RUB"

# Все доступные фиатные валюты
fiats = [f.value for f in Fiat]
print(fiats)
# ['USD', 'EUR', 'RUB', 'BYN', 'UAH', 'GBP', 'CNY', 'KZT', 'UZS', 'GEL', 'TRY', 'AED']
🏷️

Enum CurrencyType, InvoiceStatus, CheckStatus, UpdateType, PaidBtnName

Остальные Enum'ы покрывают статусы, типы и кнопки. Рассмотрим каждый:

CurrencyType — тип валюты счёта

Значение Строка Описание
CurrencyType.CRYPTO "crypto" Криптовалютный счёт. Используется с параметром asset.
CurrencyType.FIAT "fiat" Фиатный счёт. Используется с параметром fiat.

InvoiceStatus — статус инвойса

Значение Строка Описание
InvoiceStatus.ACTIVE "active" Счёт активен, ожидает оплаты
InvoiceStatus.PAID "paid" Счёт оплачен
InvoiceStatus.EXPIRED "expired" Срок счёта истёк, оплата невозможна

CheckStatus — статус чека

Значение Строка Описание
CheckStatus.ACTIVE "active" Чек активен, может быть активирован
CheckStatus.ACTIVATED "activated" Чек уже активирован получателем

UpdateType — тип обновления

Значение Строка Описание
UpdateType.INVOICE_PAID "invoice_paid" Инвойс был оплачен

PaidBtnName — кнопка после оплаты

Значение Строка Текст кнопки
PaidBtnName.VIEWITEM "viewItem" «View Item» / «Посмотреть товар»
PaidBtnName.OPENCHANNEL "openChannel" «Open Channel» / «Открыть канал»
PaidBtnName.OPENBOT "openBot" «Open Bot» / «Открыть бота»
PaidBtnName.CALLBACK "callback" «Send» / «Отправить» (callback)
Python · Использование всех Enum'ов
from aiosend import (
    CurrencyType,
    InvoiceStatus,
    CheckStatus,
    UpdateType,
    PaidBtnName,
)

# CurrencyType
print(CurrencyType.CRYPTO.value)  # "crypto"

# InvoiceStatus — проверка статуса
if invoice.status == InvoiceStatus.PAID.value:
    print("Инвойс оплачен!")
elif invoice.status == InvoiceStatus.EXPIRED.value:
    print("Инвойс просрочен")

# CheckStatus
if check.status == CheckStatus.ACTIVATED.value:
    print("Чек активирован")

# UpdateType — для фильтрации обновлений
update_type = UpdateType.INVOICE_PAID

# PaidBtnName — для create_invoice
invoice = await cp.create_invoice(
    amount=25,
    asset="USDT",
    paid_btn_name=PaidBtnName.VIEWITEM.value,
    paid_btn_url="https://example.com/item",
)

💡 Enum vs строка

Все Enum'ы имеют метод .value, который возвращает строковое значение. В большинстве методов aiosend можно передавать как сам Enum (Asset.USDT), так и строку ("USDT"). Рекомендуется использовать Enum для защиты от опечаток.

🧬

CryptoPayObject — базовая Pydantic-модель

CryptoPayObject — это базовый класс для всех моделей данных в aiosend. Он наследуется от Pydantic BaseModel и предоставляет стандартные методы сериализации, валидации и работы с данными.

Python · Иерархия наследования
pydantic.BaseModel
  └── aiosend.CryptoPayObject        # базовый класс для всех моделей
        ├── App                      # информация о приложении
        ├── Invoice                  # счёт (инвойс)
        ├── Check                    # крипто-чек
        ├── Transfer                 # перевод
        ├── Balance                  # баланс валюты
        ├── Currency                 # информация о валюте
        ├── ExchangeRate             # курс обмена
        ├── AppStats                 # статистика приложения
        ├── Update                   # обновление (событие)
        └── Error                    # ошибка API

Каждая модель наследует все возможности Pydantic: валидацию типов, преобразование данных, сериализацию.

Python · CryptoPayObject — базовые методы
from aiosend import CryptoPayObject

# Все модели наследуют от CryptoPayObject
# который наследует от pydantic.BaseModel

# У каждой модели есть:
obj.model_dump()           # сериализация в dict (Pydantic v2)
obj.model_dump_json()      # сериализация в JSON-строку
obj.model_fields           # словарь полей модели
obj.model_fields_set       # множество установленных полей

⚠️ CryptoPayObject vs BaseModel

В aiosend используется Pydantic v2. Все модели наследуются от CryptoPayObject, который добавляет специфические для Crypto Pay методы и настройки. Не пытайся создавать экземпляры CryptoPayObject напрямую — используй конкретные модели (App, Invoice и т.д.).

📦

Сериализация: dict() и model_dump()

Все объекты aiosend можно сериализовать в словарь или JSON. Это полезно для логирования, сохранения в базу данных или передачи по сети.

Метод dict() (Pydantic v1 style)

Старый метод dict() всё ещё доступен для обратной совместимости, но рекомендуется использовать model_dump():

Python · Сериализация в словарь
import json
from aiosend import CryptoPay

cp = CryptoPay(token="TOKEN")
app = await cp.get_me()

# Pydantic v2 способ (рекомендуется)
data = app.model_dump()
print(data)
# {
#     'app_id': 12345,
#     'name': 'My App',
#     'payment_processing_bot_username': 'CryptoTestnetBot',
#     'supported_assets': [...]
# }

# Pydantic v1 способ (устаревший)
data_old = app.dict()

# Сериализация в JSON
json_str = app.model_dump_json(indent=2)
print(json_str)

# Сохранение в файл
with open("app_info.json", "w") as f:
    f.write(app.model_dump_json(indent=2))

# Загрузка из JSON
json_data = '{"app_id": 12345, "name": "App", ...}'
app_loaded = App.model_validate_json(json_data)

Параметры model_dump()

Python · Параметры сериализации
from aiosend import CryptoPay

cp = CryptoPay(token="TOKEN")
invoice = await cp.create_invoice(amount=100, asset="USDT")

# Только заданные поля (исключая None)
data1 = invoice.model_dump(exclude_none=True)

# Только определённые поля
data2 = invoice.model_dump(
    include={"invoice_id", "amount", "asset", "status"}
)

# Исключить определённые поля
data3 = invoice.model_dump(
    exclude={"bot_invoice_url", "mini_app_invoice_url"}
)

# Вложенная сериализация (по умолчанию True)
data4 = invoice.model_dump(mode="json")  # для JSON-сериализации

💡 model_dump vs dict

В Pydantic v2 метод dict() помечен как deprecated. Используй model_dump() для новых проектов. Он принимает те же параметры: include, exclude, exclude_none, by_alias, mode.

Десериализация — создание объектов из данных

Ты можешь создавать модели aiosend из словарей или JSON. Это полезно, когда ты сохраняешь данные в БД и потом загружаешь их:

Python · Создание объектов из данных
from aiosend import App, Invoice, Balance

# Из словаря
app_data = {
    "app_id": 12345,
    "name": "My App",
    "payment_processing_bot_username": "CryptoBot",
    "supported_assets": [],
}
app = App.model_validate(app_data)
print(app.name)  # "My App"

# Из JSON
json_str = '{"invoice_id": 1, "amount": "100", "asset": "USDT", ...}'
invoice = Invoice.model_validate_json(json_str)

# Частичное создание (с дефолтными значениями)
balance = Balance(
    currency_code="USDT",
    available="100.50",
    onhold="0.00",
)
📋

Все типы данных aiosend — сводная таблица

В таблице ниже собраны все публичные типы данных aiosend с их описанием и методами, которые их возвращают:

Тип Категория Описание Где используется
App Модель Информация о приложении cp.get_me()
Invoice Модель Счёт на оплату с полной информацией cp.create_invoice(), cp.get_invoices()
Check Модель Крипто-чек для перевода средств cp.create_check()
Transfer Модель Перевод средств пользователю cp.transfer()
Balance Модель Баланс одной валюты (доступно + заморожено) cp.get_balance()
Currency Модель Информация о валюте (мин/макс сумма, точность) cp.get_currencies()
ExchangeRate Модель Курс обмена между двумя валютами cp.get_exchange_rates()
AppStats Модель Статистика приложения (объёмы, количество) cp.get_stats()
Update Модель Событие (например, об оплате инвойса) Polling / Webhook
Response Модель Ответ API с полями ok, result, error Внутренний тип
Error Модель Детали ошибки API (code + name) Внутренний тип, APIError
Python · Импорт всех типов
# Основные типы (доступны напрямую из aiosend)
from aiosend import (
    CryptoPayObject,     # базовый класс
    App,                 # информация о приложении
    Invoice,             # счёт
    Check,               # чек
    Transfer,            # перевод
    Balance,             # баланс
    Currency,            # валюта
    ExchangeRate,        # курс обмена
    AppStats,            # статистика
    Update,              # обновление
    Response,            # ответ API
    Error,               # ошибка API
)

# Enum'ы
from aiosend import (
    Asset,
    Fiat,
    CurrencyType,
    InvoiceStatus,
    CheckStatus,
    UpdateType,
    PaidBtnName,
)
📌

Что важно запомнить

1️⃣
12 криптоактивов в Asset. USDT, TON, BTC, ETH, LTC, BNB, TRX, USDC, JET (только TESTNET), SEND, SOL, XAUT.
2️⃣
12 фиатных валют в Fiat. USD, EUR, RUB, BYN, UAH, GBP, CNY, KZT, UZS, GEL, TRY, AED.
3️⃣
CryptoPayObject — базовый класс. Все модели наследуются от него. Используй model_dump() для сериализации, model_validate() для десериализации.
4️⃣
Enum защищают от опечаток. Используй Asset.USDT вместо "USDT" — IDE подскажет варианты и не даст ошибиться.
5️⃣
Статусы инвойса: ACTIVE → PAID или EXPIRED. Проверяй invoice.status через InvoiceStatus.PAID.value.
💻

Практическая задача

Задача: Сериализатор данных приложения

Напиши скрипт app_exporter.py, который:

  1. Создаёт клиента CryptoPay и получает App через get_me().
  2. Создаёт 2 тестовых инвойса (USDT и TON) через create_invoice().
  3. Получает балансы через get_balance().
  4. Собирает все данные в единый словарь структуры:
{
    "app": { ... },
    "invoices": [ ... ],
    "balances": [ ... ],
    "exported_at": "2024-01-01T00:00:00"
}
  1. Сохраняет этот словарь в JSON-файл app_export.json с форматированием (indent=2).
  2. Загружает файл обратно и восстанавливает объекты App через App.model_validate().

Подсказка:

# Используй model_dump() для сериализации
app_data = app.model_dump()
invoice_data = invoice.model_dump()

# Используй model_dump_json() для записи в файл
with open("export.json", "w") as f:
    f.write(json.dumps(data, indent=2))

# Используй model_validate() для восстановления
app_restored = App.model_validate(loaded_data["app"])
📊

Сравнение всех моделей данных

Ниже приведена сравнительная таблица всех Pydantic-моделей aiosend с указанием количества полей и ключевых особенностей каждой:

Модель Поля Ключевые поля Метод получения
App 4 app_id, name, payment_processing_bot_username, supported_assets get_me()
Invoice 25+ invoice_id, amount, asset, status, bot_invoice_url create_invoice(), get_invoices()
Check 10+ check_id, amount, asset, status, bot_check_url create_check()
Transfer 6+ transfer_id, amount, asset, user_id, status transfer()
Balance 3 currency_code, available, onhold get_balance()
Currency 6+ currency_code, min_amount, max_amount, decimals get_currencies()
ExchangeRate 3 source, target, rate get_exchange_rates()
AppStats 5+ volume, transactions_count, paid_users_count get_stats()

💡 Все модели поддерживают сравнение

Pydantic-модели поддерживают сравнение через ==. Две модели равны, если все их поля совпадают. Это удобно для тестирования: assert invoice1 == invoice2.

Практический пример: обход всех моделей

Python · Получение всех типов данных
import asyncio
from aiosend import CryptoPay
from aiosend.types import (
    App, Invoice, Check, Transfer,
    Balance, Currency, ExchangeRate, AppStats,
)

async def explore_all_types():
    cp = CryptoPay(token="TOKEN")

    # 1. App
    app: App = await cp.get_me()
    print(f"App: {app.name}")

    # 2. Invoice
    invoice: Invoice = await cp.create_invoice(
        amount=10, asset="USDT",
    )
    print(f"Invoice: #{invoice.invoice_id}")

    # 3. Balance
    balances: list[Balance] = await cp.get_balance()
    for b in balances:
        print(f"Balance: {b.currency_code}")

    # 4. Currency
    currencies: list[Currency] = await cp.get_currencies()
    for c in currencies:
        print(f"Currency: {c.currency_code}")

    # 5. ExchangeRate
    rates: list[ExchangeRate] = await cp.get_exchange_rates()
    for r in rates:
        print(f"Rate: {r.source}→{r.target} = {r.rate}")

    # 6. AppStats
    stats: AppStats = await cp.get_stats()
    print(f"Stats: volume={stats.volume}")

asyncio.run(explore_all_types())
📊

Asset как Pydantic-модель (не путать с Enum)

В aiosend есть два разных понятия с похожими названиями: Enum Asset (перечисление криптовалют) и Pydantic-модель Asset (объект с данными о валюте). Не путай их! Pydantic-модель Asset возвращается в поле supported_assets объекта App и содержит подробную информацию о криптовалюте.

Поле модели Тип Описание
asset_code str Код валюты (например "USDT", "TON")
asset_name str Полное название (например "Tether", "Toncoin")
decimals int Количество знаков после запятой
is_blockchain bool Является ли актив самостоятельным блокчейном
Python · Pydantic Asset vs Enum Asset
from aiosend import CryptoPay, Asset as AssetEnum
from aiosend.types import Asset as AssetModel

cp = CryptoPay(token="TOKEN")
app = await cp.get_me()

# Pydantic-модель Asset (из supported_assets)
for asset_model in app.supported_assets:
    print(f"{asset_model.asset_code}: {asset_model.asset_name}")
    print(f"  Decimals: {asset_model.decimals}")
    print(f"  Is blockchain: {asset_model.is_blockchain}")

# Enum Asset (для указания валюты в методах)
print(AssetEnum.USDT)       # Asset.USDT (Enum)
print(AssetEnum.USDT.value) # "USDT" (строка)

# Сравнение с Enum по коду
for asset_model in app.supported_assets:
    if asset_model.asset_code == AssetEnum.TON.value:
        print(f"Найден TON: {asset_model.asset_name}")

💡 Где что использовать?

Enum Asset используется для указания валюты в методах API (create_invoice(asset="USDT")). Pydantic-модель Asset используется для получения информации о валюте (название, decimals). Не путай их!

Урок 2.4: Типы данных и Enum'ы

5 вопросов