Mock Telegram Bot API for BDD testing
Project description
Telemelya — Mock Telegram Bot API
Фреймворк для BDD-тестирования Telegram-ботов. Предоставляет mock-сервер Telegram Bot API (FastAPI + Redis + MinIO) и Python-клиент для тестирования с интеграцией behave/Gherkin.
Содержание
- Архитектура
- Быстрый старт
- Конфигурация mock-сервера
- API mock-сервера
- Тестовый клиент
- BDD-тестирование
- Изоляция сессий
- Поддержка нескольких ботов
- Адаптер для aiogram
- Примеры типовых архитектур
- CI/CD
- Рекомендации
- Лицензия
Архитектура
Тестовый клиент (behave) → Mock Telegram Bot API → Бот (webhook)
├── Redis (состояние)
└── MinIO (медиа)
- Бот регистрирует webhook на mock-сервере
- Тестовый клиент отправляет обновления через Control API → mock-сервер доставляет их на webhook бота
- Бот обрабатывает обновление и вызывает эндпоинты Bot API mock-сервера (
sendMessage,sendPhotoи т.д.) - Mock-сервер записывает ответы в Redis, медиа — в MinIO
- Тестовый клиент получает ответы и проверяет их
Быстрый старт
Локальная разработка
- Скопируйте
.env.exampleв.envи при необходимости измените настройки - Запустите инфраструктуру:
make local-up - Запустите вашего бота, указав mock-сервер:
TELEMELYA_URL=http://localhost:8080 BOT_TOKEN=123456:ABC python your_bot.py
- Запустите тесты:
pip install -r requirements-client.txt make test
- Остановка:
make local-down
Развёртывание на сервере (VPS)
- Настройте
.env— укажите домен, учётные данные MinIO и API-ключи - Обновите
Caddyfile, указав ваш домен - Развёрните:
docker compose up -d
- Укажите вашему боту
TELEMELYA_URL=https://mock.ваш-домен.com
Конфигурация mock-сервера
Все настройки задаются через переменные окружения (см. .env.example):
| Переменная | По умолчанию | Описание |
|---|---|---|
MOCK_SERVER_HOST |
0.0.0.0 |
Хост для привязки сервера |
MOCK_SERVER_PORT |
8080 |
Порт сервера |
MOCK_SERVER_URL |
http://localhost:8080 |
Публичный URL mock-сервера |
REDIS_URL |
redis://localhost:6379/0 |
URL подключения к Redis |
MINIO_ENDPOINT |
localhost:9000 |
Эндпоинт MinIO |
MINIO_ACCESS_KEY |
minioadmin |
Ключ доступа MinIO |
MINIO_SECRET_KEY |
minioadmin |
Секретный ключ MinIO |
MINIO_BUCKET |
test-media |
Имя бакета MinIO |
MINIO_USE_SSL |
false |
Использовать SSL для MinIO |
AUTH_KEYS |
`` | API-ключи через запятую |
API mock-сервера
Bot API (/bot{token}/...)
Эмулирует api.telegram.org:
| Метод | Эндпоинт | Описание |
|---|---|---|
| POST | /bot{token}/getMe |
Информация о боте |
| POST | /bot{token}/setWebhook |
Регистрация webhook |
| POST | /bot{token}/deleteWebhook |
Удаление webhook |
| POST | /bot{token}/sendMessage |
Отправка текстового сообщения |
| POST | /bot{token}/sendPhoto |
Отправка фото |
| POST | /bot{token}/getFile |
Получение информации о файле |
| GET | /bot{token}/file/{file_path} |
Скачивание файла |
| POST | /bot{token}/answerCallbackQuery |
Ответ на callback-запрос |
| POST | /bot{token}/editMessageText |
Редактирование сообщения |
Control API (/api/v1/test/...)
Требует заголовок Authorization: Bearer <api_key>:
| Метод | Эндпоинт | Описание |
|---|---|---|
| POST | /api/v1/test/send_update?bot_token=... |
Отправить обновление боту |
| GET | /api/v1/test/responses?session_id=... |
Получить ответы бота |
| GET | /api/v1/test/responses/wait?session_id=...&timeout=5 |
Ожидание ответа (long-poll) |
| POST | /api/v1/test/reset?session_id=... |
Сброс состояния сессии |
| GET | /api/v1/test/media/{file_id}?session_id=... |
Скачать медиафайл |
| GET | /api/v1/test/health |
Проверка работоспособности |
Тестовый клиент
from telemelya.client import TelegramTestClient, ResponseCollector
client = TelegramTestClient(
server_url="http://localhost:8080",
api_key="ваш-api-ключ",
bot_token="токен-бота",
)
collector = ResponseCollector(client)
# Отправить команду
client.send_command(chat_id=12345, command="/start")
# Дождаться ответа и проверить
collector.wait_for_response(timeout=5.0)
collector.assert_text("Добро пожаловать!")
# Очистка
client.reset()
client.close()
Методы TelegramTestClient
| Метод | Описание |
|---|---|
send_message(chat_id, text) |
Отправить текстовое сообщение |
send_command(chat_id, command) |
Отправить команду (например, /start) |
send_photo(chat_id, photo_path, caption=) |
Отправить фото |
send_callback_query(chat_id, data, message_id) |
Отправить callback-запрос |
get_responses() |
Получить все ответы бота |
wait_for_response(timeout=5.0) |
Дождаться ответа (long-poll) |
get_media(file_id) |
Скачать медиафайл |
reset() |
Сбросить состояние сессии |
close() |
Закрыть соединение |
Методы ResponseCollector
| Метод | Описание |
|---|---|
wait_for_response(timeout=5.0) |
Дождаться ответа и сохранить |
assert_text(expected) |
Проверить точное совпадение текста |
assert_contains(substring) |
Проверить наличие подстроки |
assert_photo() |
Проверить, что ответ содержит фото |
assert_reply_markup() |
Проверить наличие клавиатуры |
last |
Последний полученный ответ |
BDD-тестирование
Сценарии на Gherkin с поддержкой русского языка:
# language: ru
Функционал: Обработка команды /start
Сценарий: Пользователь запускает бота
Допустим chat_id "12345"
Когда пользователь отправляет команду "/start"
Тогда бот отвечает "Добро пожаловать!"
Встроенные шаги
| Шаг | Описание |
|---|---|
Допустим chat_id "{id}" |
Задать ID чата |
Когда пользователь отправляет сообщение "{text}" |
Отправить текстовое сообщение |
Когда пользователь отправляет команду "{command}" |
Отправить команду |
Когда пользователь отправляет фото "{path}" |
Отправить фото |
Тогда бот отвечает "{text}" |
Проверить точный текст ответа |
Тогда ответ содержит "{substring}" |
Проверить наличие подстроки |
Тогда бот отправляет фото |
Проверить, что ответ — фото |
Тогда бот отправляет фото с подписью "{caption}" |
Проверить фото с подписью |
Запуск тестов
# Все тесты
python -m behave tests/features/
# Конкретный feature-файл
python -m behave tests/features/start_command.feature
# С генерацией отчёта Allure
python -m behave tests/features/ -f allure_behave.formatter:AllureFormatter -o allure-results
allure serve allure-results
Изоляция сессий
Каждый тестовый сценарий получает уникальный session_id (UUID). Клиент передаёт его через заголовок X-Test-Session. Это позволяет запускать тесты параллельно без конфликтов.
Поддержка нескольких ботов
Mock-сервер различает ботов по {token} в URL-путях. Один сервер может обслуживать несколько ботов одновременно.
Пример echo-бота
См. examples/echo_bot/ — минимальный aiogram echo-бот, настроенный для работы с Telemelya.
Создание бот-сервисов с адаптером telemelya.aiogram
Адаптер telemelya.aiogram позволяет писать код бота один раз и запускать его как в продакшне (с реальным Telegram API), так и в тестовом режиме (с mock-сервером Telemelya). Переключение — только через переменные окружения, без изменения кода.
Принцип работы
┌──────────────────────┐
Ваш код бота │ Dispatcher + │
(хендлеры) │ TemelyaRunner │
└──────────┬───────────┘
│
┌─────────────┴─────────────┐
│ TELEMELYA_URL задан? │
├─── Да ────────────────┐ │
│ Bot → Mock Server │ │
│ Режим: webhook │ │
├─── Нет ───────────────┤ │
│ Bot → api.telegram │ │
│ Режим: polling │ │
└───────────────────────────┘
Быстрый старт адаптера
1. Установите зависимости
pip install telemelya[aiogram]
# или
pip install aiogram aiohttp-socks
2. Создайте бота
# my_bot.py
from aiogram import Dispatcher, types
from aiogram.filters import CommandStart
from telemelya.aiogram import TemelyaRunner
dp = Dispatcher()
@dp.message(CommandStart())
async def handle_start(message: types.Message):
await message.answer("Привет! Я ваш бот.")
@dp.message()
async def handle_echo(message: types.Message):
await message.answer(message.text or "")
if __name__ == "__main__":
runner = TemelyaRunner(dp)
runner.run()
Это весь код. Дальше — только переменные окружения.
3. Локальный запуск для отладки (polling)
По умолчанию, без TELEMELYA_URL и WEBHOOK_URL, бот запускается в polling-режиме — удобно для локальной разработки и отладки:
BOT_TOKEN=123456789:REAL_TOKEN python my_bot.py
Бот подключится к api.telegram.org, удалит старый webhook и начнёт polling.
С прокси:
BOT_TOKEN=123456789:REAL_TOKEN \
PROXY_URL=http://127.0.0.1:12334 \
python my_bot.py
4. Продакшн (webhook)
На сервере боты обычно работают через webhook — Telegram сам отправляет обновления на ваш публичный URL. Задайте WEBHOOK_URL:
BOT_TOKEN=123456789:REAL_TOKEN \
WEBHOOK_URL=https://bot.example.com \
python my_bot.py
Адаптер автоматически выберет webhook-режим при наличии WEBHOOK_URL.
5. Запуск в тестовом режиме (Telemelya)
# Сначала поднимите mock-сервер
docker compose -f docker-compose.local.yml up -d
# Запустите бота, указав TELEMELYA_URL
TELEMELYA_URL=http://127.0.0.1:8080 python my_bot.py
Бот автоматически:
- Подключится к mock-серверу вместо Telegram
- Зарегистрирует webhook (с
host.docker.internalдля Docker) - Начнёт принимать тестовые обновления
6. Напишите тесты
# test_my_bot.py
from telemelya.client import TelegramTestClient, ResponseCollector
client = TelegramTestClient(
server_url="http://127.0.0.1:8080",
api_key="test-api-key-12345",
bot_token="123456789:ABCDefGhIjKlMnOpQrStUvWxYz",
)
collector = ResponseCollector(client)
# Отправить /start → проверить ответ
client.send_command(chat_id=12345, command="/start")
collector.wait_for_response(timeout=5.0)
collector.assert_text("Привет! Я ваш бот.")
client.reset()
client.close()
Или через BDD (Gherkin):
# language: ru
Функционал: Основные команды бота
Сценарий: Пользователь запускает бота
Допустим chat_id "12345"
Когда пользователь отправляет команду "/start"
Тогда бот отвечает "Привет! Я ваш бот."
Сценарий: Эхо-ответ
Допустим chat_id "12345"
Когда пользователь отправляет сообщение "Тест"
Тогда бот отвечает "Тест"
API адаптера
create_bot(token, *, mock_url, proxy) → Bot
Фабрика для создания aiogram.Bot с нужной конфигурацией.
| Параметр | Env-переменная | Описание |
|---|---|---|
token |
BOT_TOKEN |
Токен бота (обязательный) |
mock_url |
TELEMELYA_URL |
URL mock-сервера. Если задан → тестовый режим |
proxy |
PROXY_URL |
HTTP/SOCKS прокси (только продакшн) |
Приоритет: параметр функции → переменная окружения.
from telemelya.aiogram import create_bot
# Тест
bot = create_bot(token="fake:token", mock_url="http://localhost:8080")
# Продакшн
bot = create_bot() # читает BOT_TOKEN из env
TemelyaRunner(dp, **kwargs)
Запускает Dispatcher в нужном режиме.
| Параметр | Env-переменная | По умолчанию | Описание |
|---|---|---|---|
dp |
— | — | aiogram Dispatcher (обязательный) |
bot |
— | None |
Готовый Bot (если None, создаётся через create_bot) |
token |
BOT_TOKEN |
— | Токен (если bot не передан) |
mock_url |
TELEMELYA_URL |
"" |
URL mock-сервера |
proxy |
PROXY_URL |
"" |
HTTP/SOCKS прокси |
mode |
BOT_RUN_MODE |
"auto" |
Режим: auto, polling, webhook |
webhook_url |
WEBHOOK_URL |
"" |
Публичный URL для webhook |
webhook_host |
WEBHOOK_HOST |
0.0.0.0 |
Хост для webhook-сервера |
webhook_port |
WEBHOOK_PORT |
8081 |
Порт для webhook-сервера |
webhook_path |
— | /webhook |
Путь для webhook-эндпоинта |
Автоматическое определение режима (при BOT_RUN_MODE=auto):
TELEMELYA_URL |
WEBHOOK_URL |
Режим | Сценарий |
|---|---|---|---|
| ✅ | — | webhook → mock | Тесты (Telemelya) |
| — | ✅ | webhook → Telegram | Продакшн (сервер) |
| — | — | polling ← Telegram | Локальная отладка |
Можно переопределить через BOT_RUN_MODE=polling или BOT_RUN_MODE=webhook.
runner = TemelyaRunner(dp)
runner.run() # Блокирующий запуск
await runner.start() # Асинхронный запуск
Свойства:
runner.is_test_mode—Trueесли работает через mockrunner.effective_mode— текущий режим (RunMode.POLLING/RunMode.WEBHOOK)
Переменные окружения адаптера
| Переменная | Обязательная | Описание |
|---|---|---|
BOT_TOKEN |
Да (продакшн) | Токен бота от @BotFather |
TELEMELYA_URL |
Нет | URL Telemelya. Если задан — тестовый режим |
PROXY_URL |
Нет | HTTP/SOCKS5 прокси (продакшн) |
WEBHOOK_URL |
Нет | Публичный URL для webhook (продакшн) |
BOT_RUN_MODE |
Нет | auto (по умолчанию), polling, webhook |
WEBHOOK_HOST |
Нет | Хост для webhook-сервера (0.0.0.0) |
WEBHOOK_PORT |
Нет | Порт для webhook-сервера (8081) |
WEBHOOK_EXTERNAL_HOST |
Нет | Хост для webhook URL в тесте (host.docker.internal) |
Примеры типовых архитектур
Простой бот (один файл)
# bot.py
from aiogram import Dispatcher, types, F
from aiogram.filters import CommandStart, Command
from telemelya.aiogram import TemelyaRunner
dp = Dispatcher()
@dp.message(CommandStart())
async def cmd_start(message: types.Message):
await message.answer("Добро пожаловать!", reply_markup=...)
@dp.message(Command("help"))
async def cmd_help(message: types.Message):
await message.answer("Список команд: /start, /help, /settings")
@dp.message(F.photo)
async def on_photo(message: types.Message):
await message.answer("Фото получено!")
@dp.message()
async def on_text(message: types.Message):
# Бизнес-логика обработки текста
result = process_text(message.text)
await message.answer(result)
if __name__ == "__main__":
TemelyaRunner(dp).run()
Бот с роутерами (многофайловый)
my_bot/
├── main.py # Точка входа
├── handlers/
│ ├── __init__.py
│ ├── start.py # /start, /help
│ ├── photos.py # Обработка фото
│ └── payments.py # Платежи
├── services/
│ └── ai_service.py # Бизнес-логика
└── docker-compose.test.yml
# my_bot/handlers/start.py
from aiogram import Router, types
from aiogram.filters import CommandStart
router = Router()
@router.message(CommandStart())
async def cmd_start(message: types.Message):
await message.answer("Привет!")
# my_bot/main.py
from aiogram import Dispatcher
from telemelya.aiogram import TemelyaRunner
from handlers.start import router as start_router
from handlers.photos import router as photo_router
dp = Dispatcher()
dp.include_router(start_router)
dp.include_router(photo_router)
if __name__ == "__main__":
TemelyaRunner(dp).run()
Docker Compose для тестирования
# docker-compose.test.yml
services:
mock-server:
image: ghcr.io/fedottech/telemelya:latest
ports: ["8080:8080"]
depends_on: [redis, minio]
environment:
REDIS_URL: redis://redis:6379/0
MINIO_ENDPOINT: minio:9000
AUTH_KEYS: test-key-123
my-bot:
build: .
depends_on: [mock-server]
environment:
BOT_TOKEN: "123456789:ABCDefGhIjKlMnOpQrStUvWxYz"
TELEMELYA_URL: "http://mock-server:8080"
WEBHOOK_HOST: "0.0.0.0"
WEBHOOK_PORT: "8081"
redis:
image: redis:7-alpine
minio:
image: minio/minio
command: server /data
CI/CD (GitHub Actions)
# .github/workflows/bot-tests.yml
name: Bot Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
services:
redis:
image: redis:7-alpine
ports: [6379:6379]
minio:
image: minio/minio
ports: [9000:9000]
env:
MINIO_ROOT_USER: minioadmin
MINIO_ROOT_PASSWORD: minioadmin
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Установка зависимостей
run: pip install telemelya[client,aiogram] behave
- name: Запуск mock-сервера
run: |
pip install telemelya
telemelya-server &
sleep 3
env:
REDIS_URL: redis://localhost:6379/0
AUTH_KEYS: test-key
- name: Запуск тестируемого бота
run: |
python my_bot/main.py &
sleep 2
env:
TELEMELYA_URL: http://localhost:8080
BOT_TOKEN: "123456789:FakeTestToken"
- name: Запуск BDD-тестов
run: behave tests/features/
env:
MOCK_SERVER_URL: http://localhost:8080
API_KEY: test-key
Рекомендации
- Не храните токен в коде — всегда через
BOT_TOKENenv-переменную - Один entry-point — используйте
TemelyaRunner(dp).run()как единственную точку запуска - Фейковый токен для тестов — формат
123456789:ABCDefGhIjKlMnOpQrStUvWxYz(aiogram валидирует формат) - Изоляция тестов — каждый тест-сценарий получает уникальный
session_id, тесты не мешают друг другу - Прокси только для продакшна —
PROXY_URLигнорируется в тестовом режиме - Windows + Docker Desktop — в тестовом клиенте используйте
127.0.0.1вместоlocalhost(проблема с IPv6) - Системный прокси Windows — если в системе настроен HTTP-прокси (корпоративный VPN, антивирус и т.д.), Python-библиотека httpx будет направлять запросы к
localhostчерез прокси, что вызовет ошибкуReadError: [WinError 10054]. Решение — задайтеNO_PROXY=localhost,127.0.0.1перед запуском тестов, либо используйте127.0.0.1вместоlocalhost:NO_PROXY=localhost,127.0.0.1 make test
Установка
Telemelya состоит из нескольких компонентов, которые устанавливаются отдельно в зависимости от вашей роли:
Адаптер для aiogram
Для разработчиков ботов — TemelyaRunner, create_bot. Позволяет запускать бот с Telemelya или с реальным Telegram без изменения кода. Не включает сервер и тестовый клиент.
pip install telemelya[aiogram]
Тестовый клиент + BDD
Для QA и тестировщиков — TelegramTestClient, ResponseCollector, behave-шаги. Не включает сервер и адаптер для aiogram.
pip install telemelya[client]
Всё для разработки
Все компоненты + pytest, allure. Для разработки самого Telemelya или полного цикла «написать бота + протестировать».
pip install telemelya[dev]
Только mock-сервер
Серверная часть — для запуска mock Telegram Bot API без Docker. Требует внешние Redis и MinIO. Используйте, если хотите развернуть сервер вручную (на VPS, в CI/CD и т.д.).
pip install telemelya
# Запуск (Redis и MinIO должны быть доступны):
REDIS_URL=redis://localhost:6379/0 MINIO_ENDPOINT=localhost:9000 telemelya-server
Большинству пользователей Docker-образ удобнее:
docker pull ghcr.io/fedottech/telemelya:main— он уже включает сервер, достаточно поднять Redis и MinIO черезdocker-compose.
pip install telemelya[dev]
Структура проекта
Telemelya/
├── telemelya/
│ ├── server/
│ │ ├── app.py # FastAPI-приложение, точка входа сервера
│ │ ├── config.py # Конфигурация (Pydantic Settings)
│ │ ├── state.py # Redis: webhook-реестр, логи ответов, сессии
│ │ ├── media.py # MinIO: загрузка/скачивание медиафайлов
│ │ ├── bot_api.py # Эмуляция Bot API (/bot{token}/...)
│ │ ├── control_api.py # Control API (/api/v1/test/...)
│ │ ├── webhook.py # Доставка обновлений на webhook бота
│ │ └── auth.py # Аутентификация по API-ключу
│ ├── client/
│ │ ├── client.py # TelegramTestClient (httpx)
│ │ └── collector.py # ResponseCollector (assertions)
│ ├── aiogram.py # Адаптер TemelyaRunner для aiogram
│ └── models.py # Pydantic-модели Telegram API
├── tests/
│ ├── features/ # Gherkin-сценарии (.feature)
│ ├── steps/ # Шаги behave (Python)
│ ├── environment.py # Хуки behave (setup/teardown)
│ └── test_integration.py # Интеграционные тесты
├── examples/
│ └── echo_bot/ # Пример echo-бота
├── docker-compose.local.yml # Docker Compose для разработки
├── docker-compose.yml # Docker Compose для продакшна
├── Dockerfile # Multi-stage Dockerfile
├── Makefile # Удобные команды
└── pyproject.toml # Конфигурация Python-пакета
Лицензия
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file telemelya-0.1.1.tar.gz.
File metadata
- Download URL: telemelya-0.1.1.tar.gz
- Upload date:
- Size: 32.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
55165226087160375211579665182e2ee550521a642bb98c9aa039f19e2fc900
|
|
| MD5 |
f0f62da6126b1c80f18e7d5abd7443b2
|
|
| BLAKE2b-256 |
8255ecc933d049cd29fefd4248cd7142ca4b907596f8a8d7029065035f5eacc6
|
Provenance
The following attestation bundles were made for telemelya-0.1.1.tar.gz:
Publisher:
publish.yml on FedotTech/Telemelya
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
telemelya-0.1.1.tar.gz -
Subject digest:
55165226087160375211579665182e2ee550521a642bb98c9aa039f19e2fc900 - Sigstore transparency entry: 1134788055
- Sigstore integration time:
-
Permalink:
FedotTech/Telemelya@a9efa49e52f2d535666b7a80579316bac7586d12 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/FedotTech
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@a9efa49e52f2d535666b7a80579316bac7586d12 -
Trigger Event:
release
-
Statement type:
File details
Details for the file telemelya-0.1.1-py3-none-any.whl.
File metadata
- Download URL: telemelya-0.1.1-py3-none-any.whl
- Upload date:
- Size: 27.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6e5c3f9aeff7792accf49af21c2d662790a2d59a4696bc0697feef0d06f7f5a7
|
|
| MD5 |
b00b74cbf004029cae22182dae889916
|
|
| BLAKE2b-256 |
aa78b8e3eb0604c80ff482f159ccc1f6d3b2da457496e8d6f847001a5a3ef92d
|
Provenance
The following attestation bundles were made for telemelya-0.1.1-py3-none-any.whl:
Publisher:
publish.yml on FedotTech/Telemelya
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
telemelya-0.1.1-py3-none-any.whl -
Subject digest:
6e5c3f9aeff7792accf49af21c2d662790a2d59a4696bc0697feef0d06f7f5a7 - Sigstore transparency entry: 1134788077
- Sigstore integration time:
-
Permalink:
FedotTech/Telemelya@a9efa49e52f2d535666b7a80579316bac7586d12 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/FedotTech
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@a9efa49e52f2d535666b7a80579316bac7586d12 -
Trigger Event:
release
-
Statement type: