Skip to main content

Русский DSL для Telegram ботов

Project description

🦋 Cicada

Русский язык программирования для создания Telegram-ботов

Python License PyPI version Downloads Tests Coverage Stars

Cicada — это предметно-ориентированный язык (DSL), позволяющий писать ботов для Telegram на чистом русском языке. Никакого boilerplate-кода, никакой сложной асинхронности — только логика вашего бота.


� Установка

Из PyPI (рекомендуется)

pip install cicada-studio

Из исходников

git clone https://github.com/Cicadadenis/cicada-studio.git
cd cicada-studio
pip install -e .

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

Первый бот за 30 секунд

Создайте файл привет.ccd:

бот "ВАШ_ТОКЕН_ЗДЕСЬ"

при старте:
    ответ "Привет! Я ваш первый бот на Cicada 👋"
    кнопки "Статус" "Помощь"

если текст == "Статус":
    ответ "Всё работает отлично! ✅"

если текст == "Помощь":
    ответ "Напишите что угодно, я повторю."

иначе:
    ответ "Вы написали: " + текст

Запустите:

cicada run привет.ccd

🤔 Почему Cicada?

Cicada создана чтобы упростить разработку Telegram-ботов. Никакой сложности — только ваша логика.

🎯 Решаемые проблемы

❌ Было ✅ Стало
Сложность Telegram API — куча методов, вебхуки, поллинг Декларативный DSL: ответ, кнопки, спросить
Асинхронность Python — callback'и, asyncio, await Синхронный код, скрытая асинхронность
FSM логика — сложные state machine, transitions Встроенные сценарии: сценарий, шаг, повторить шаг
Boilerplate код — 50+ строк настройки 10 строк — и бот работает

👥 Кому подходит

  • 🛒 Магазины — каталоги, корзина, заказы, оплата
  • 💬 Поддержка — тикеты, FAQ, чаты с операторами
  • 📢 Маркетинг — рассылки, опросы, розыгрыши, игры
  • 🏢 CRM — автоматизация бизнес-процессов, интеграции
  • 🤖 Чат-боты — любые диалоговые сценарии, анкеты, боты-ассистенты

📊 Сравнение

# python-telegram-bot: ~50 строк
from telegram import Update, ReplyKeyboardMarkup
from telegram.ext import Application, CommandHandler, ContextTypes

async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
    await update.message.reply_text("Привет!")

app = Application.builder().token("TOKEN").build()
app.add_handler(CommandHandler("start", start))
app.run_polling()

# Aiogram: ~40 строк
from aiogram import Bot, Dispatcher, types
bot = Bot(token="TOKEN")
dp = Dispatcher()

@dp.message(Command("start"))
async def cmd_start(message: types.Message):
    await message.answer("Привет!")

# Cicada: 10 строк
бот "TOKEN"
при старте:
    ответ "Привет!"
Решение Код для эхо-бота Сложность FSM
python-telegram-bot ~50 строк Высокая Ручная
Aiogram ~40 строк Средняя Ручная
Cicada 10 строк Низкая Встроена

🏗️ Архитектура

┌─────────────────────────────────────────────────────────────┐
│                      Пользователь                            │
│                         (Telegram)                          │
└────────────────────┬────────────────────────────────────────┘
                     │ HTTP
                     ▼
┌─────────────────────────────────────────────────────────────┐
│                   Telegram API                               │
│              (BotFather Token)                              │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│                    Cicada Runtime                           │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐       │
│  │   Parser     │→ │     AST      │→ │   Executor   │       │
│  │  (.ccd →)    │  │  (дерево)    │  │  (TG API)    │       │
│  └──────────────┘  └──────────────┘  └──────────────┘       │
│         │                 │                 │               │
│         ▼                 ▼                 ▼               │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐       │
│  │   Blocks   │  │   Runtime    │  │  Database    │       │
│  │   (globals)│  │ (user ctx)   │  │  (JSON)      │       │
│  └──────────────┘  └──────────────┘  └──────────────┘       │
└─────────────────────────────────────────────────────────────┘

Компоненты:

  • Parser — преобразует .ccd в AST
  • AST — абстрактное синтаксическое дерево
  • Executor — выполняет команды через Telegram API
  • Runtime — контекст пользователя, переменные
  • Database — JSON-хранилище состояния

💻 CLI (Командная строка)

Основные команды

# Запуск бота
cicada run bot.ccd

# Режим разработки с подробным выводом
cicada run bot.ccd --debug
cicada run bot.ccd --dev

# Автоперезагрузка при изменении файлов
cicada run bot.ccd --reload

# Проверка синтаксиса без запуска
cicada check bot.ccd

# Инициализация нового проекта
cicada init my-bot
cd my-bot
cicada run bot.ccd

Глобальные флаги

# Показать версию
cicada --version

# Справка
cicada --help
cicada run --help

Переменные окружения

# Токен можно передать через env
export CICADA_TOKEN="your:token"

# Режим отладки
export CICADA_DEBUG=1

# Путь к конфигу
export CICADA_CONFIG="./config.yaml"

🎯 Примеры проектов

В папке examples/ собраны готовые шаблоны:

Пример Описание Сложность
echo.ccd Эхо-бот с кнопками ⭐ Лёгкая
shop.ccd Магазин с корзиной ⭐⭐ Средняя
support.ccd Система тикетов ⭐⭐⭐ Сложная

Быстрый старт с примерами

# Клонируем
git clone https://github.com/Cicadadenis/cicada-studio.git
cd cicada-studio

# Устанавливаем
pip install -e .

# Запускаем пример
cd examples
cicada echo.ccd --debug

📖 Синтаксис языка

Объявление бота

бот "ВАШ_TELEGRAM_ТОКЕН"

Обработчики событий

Конструкция Описание
при старте: Команда /start
при команде "/команда": Любая команда
если текст == "...": Условие по точному совпадению
если текст содержит "...": Проверка подстроки
иначе: Блок по умолчанию

Ответы и действия

# Простой текст
ответ "Привет, мир!"

# С переменными
ответ "Привет, " + имя + "!"

# Инлайн-кнопки
кнопки "Да" "Нет" "Отмена"

# Изображение
картинка "https://example.com/photo.jpg"

# Стикер
стикер "CAACAgIAAxkBAA..."

Переменные и память

# Сохранение значения
запомни город = "Москва"
запомни счётчик = 42

# Использование в ответах
ответ "Вы выбрали: " + город

👤 Объект пользователя

Доступ к данным пользователя через точку:

ответ "Ваш ID: " + пользователь.id
ответ "Имя: " + пользователь.имя
ответ "Фамилия: " + пользователь.фамилия

Доступные свойства: id, имя, фамилия, chat_id

🔤 Функции для работы со строками

# Проверка содержимого
если содержит(текст, "купить"):
    ответ "Напишите что хотите купить"

# Проверка длины
если длина(текст) > 100:
    ответ "Слишком длинное сообщение!"

# Проверка начала строки
если начинается_с(текст, "/"):
    ответ "Это команда"

🔗 Логические операторы в условиях

# ИЛИ — хотя бы одно условие
если текст == "да" или текст == "yes":
    ответ "Согласие получено!"

# И — все условия
если содержит(текст, "бонус") и длина(текст) > 10:
    ответ "Написано про бонус и подробно"

# НЕ — отрицание
если не текст == "exit":
    ответ "Продолжаем..."

# Числовые сравнения
если баланс > 100:
    ответ "У вас достаточно средств"

🎯 Сценарии (FSM)

Cicada поддерживает многошаговые диалоги (анкеты) через сценарий:

при команде "/анкета":
    запустить регистрация

сценарий регистрация:
    спросить "Как вас зовут?" → имя
    запомни имя_пользователя = имя
    
    спросить "Сколько вам лет?" → возраст
    запомни возраст_пользователя = возраст
    
    ответ "Приятно познакомиться, " + имя_пользователя + "!"
    ответ "Вам " + возраст_пользователя + " лет. Записано ✅"

Каждый спросить приостанавливает бота и ждёт ответа пользователя, сохраняя его в указанную переменную.

🎯 Именованные шаги в сценариях

сценарий регистрация:
    шаг имя:
        спросить "Как вас зовут?" → имя
        сохранить "имя" = имя
    
    шаг возраст:
        спросить "Сколько вам лет?" → возраст
        если возраст < 18:
            ответ "Извините, только для взрослых"
            завершить сценарий
    
    ответ "Регистрация завершена!"

💾 База данных (постоянное хранение)

Данные сохраняются между сессиями:

# Сохранить значение
сохранить "баланс" = 1000
сохранить "уровень" = уровень

# Получить значение
получить "баланс" → баланс
получить "уровень" → текущий_уровень

ответ "Ваш баланс: " + баланс

🔘 Кнопки с callback

бот "ТОКЕН"

при старте:
    кнопка "Купить" -> "buy"
    кнопка "Сайт" -> url "https://example.com"

при нажатии "buy":
    ответ "Вы нажали купить!"
    сохранить "покупок" = покупок + 1

🌍 HTTP API клиент

бот "ТОКЕН"

при команде "/курс":
    http_get "https://api.exchangerate.host/latest?base=USD" → данные
    ответ "Курс получен!"
    лог данные

при команде "/отправить":
    http_post "https://hooks.slack.com/..." с "Привет!" → ответ
    ответ "Отправлено!"

📦 Пакеты и модули

версия "1.0"
бот "ТОКЕН"

# Импорт пакета из cicada_modules/shop/index.ccd
импорт "cicada.shop"
импорт "cicada.auth"

старт:
    использовать приветствие_магазина

🧱 Переиспользуемые блоки

бот "ТОКЕН"

# Определяем блок для переиспользования
блок приветствие:
    ответ "Привет, {имя}! 👋"
    кнопки "Каталог" "Корзина"

старт:
    использовать приветствие

при нажатии "Каталог":
    использовать приветствие
    ответ "Вот наш каталог:"

🎯 Валидация в FSM сценариях

сценарий регистрация:
    шаг возраст:
        спросить "Сколько вам лет?" → возраст
        если не число(возраст):
            ответ "Пожалуйста, введите число!"
            повторить шаг
        если возраст < 18:
            ответ "Извините, только для взрослых"
            завершить сценарий
    
    шаг email:
        спросить "Введите email:" → email
        если не содержит(email, "@"):
            ответ "Некорректный email!"
            повторить шаг

🌐 Middleware (до/после каждого сообщения)

бот "ТОКЕН"

# Выполняется перед каждым сообщением
до каждого:
    лог "Пользователь {пользователь.имя} написал: {текст}"
    получить "посещений" → счётчик
    запомни счётчик = счётчик + 1
    сохранить "посещений" = счётчик

# Выполняется после каждого сообщения
после каждого:
    если счётчик > 10:
        ответ "Вы активный пользователь! 🌟"

старт:
    ответ "Добро пожаловать!"

💰 Типы данных и переменные

# Разные типы данных
пусть баланс = 1000                    # число
пусть активен = истина                 # логический
пусть бан = ложь                       # логический
пусть товары = ["A", "B", "C"]         # массив
пусть цены = [100, 200, 300]          # массив чисел

# Глобальная переменная (доступна всем)
глобально админ_id = 123456

# Проверка типов
если тип(баланс) == "число":
    ответ "Баланс корректен"

если активен == истина:
    ответ "Аккаунт активен"

🔀 Навигация в сценариях

сценарий мастер_настройки:
    шаг язык:
        спросить "Выберите язык (ru/en):" → язык
        если язык == "en":
            сохранить "lang" = "en"
            перейти к шаг готов
        сохранить "lang" = "ru"
    
    шаг уведомления:
        спросить "Включить уведомления? (да/нет)" → ответ
        если ответ == "да":
            сохранить "notif" = истина
        иначе:
            сохранить "notif" = ложь
            вернуть  # выходим из шага, но сценарий продолжается
    
    шаг готов:
        ответ "Настройка завершена!"

📸 Обработка медиа и файлов

# При получении фото
при фото:
    получить "фото_счет" → счет
    запомни счет = счет + 1
    сохранить "фото_счет" = счет
    ответ "📸 Получено фото #{счет}"
    переслать фото "Спасибо за фото!"

# При получении документа
при документ:
    ответ "📄 Получен файл: {имя_файла}"
    ответ "Размер: {размер_файла} байт"

# При получении голосового сообщения
при голос:
    ответ "🎤 Голосовое получено!"
    # Сохраняем file_id для дальнейшей обработки
    сохранить "voice_id" = файл_id

# При получении локации
при локации:
    ответ "📍 Получены координаты:"
    ответ "Широта: {широта}"
    ответ "Долгота: {долгота}"

# При получении контакта
при контакте:
    ответ "👤 Контакт получен:"
    ответ "Имя: {имя_контакта}"
    ответ "Телефон: {телефон_контакта}"

🎨 Полный пример бота магазина

версия "1.0"
бот "ВАШ_ТОКЕН"

# Команды меню Telegram
команды:
    "/start" - "Запуск бота"
    "/catalog" - "Каталог товаров"
    "/cart" - "Корзина"
    "/support" - "Поддержка"

# Глобальные настройки
глобально магазин_открыт = истина
глобально админ_id = 123456789

# Блок приветствия
блок приветствие:
    ответ "👋 Привет, {пользователь.имя}!"
    ответ "Добро пожаловать в наш магазин"
    кнопки "Каталог 🛍" "Корзина 🛒" "Поддержка 💬"

старт:
    если не магазин_открыт:
        ответ "🚫 Магазин временно закрыт"
        вернуть
    использовать приветствие

команда "/catalog":
    запустить каталог

команда "/cart":
    получить "cart" → корзина
    если тип(корзина) != "массив":
        ответ "🛒 Корзина пуста"
    иначе:
        ответ "🛒 В корзине {длина(корзина)} товаров"

при нажатии "Каталог 🛍":
    использовать приветствие

при нажатии "Поддержка 💬":
    запустить поддержка

# FSM сценарий каталога
сценарий каталог:
    шаг выбор:
        ответ "📦 Доступные товары:"
        кнопка "Товар A - 100₽" -> "buy_a"
        кнопка "Товар B - 200₽" -> "buy_b"
        кнопка "Назад" -> "back"
    
    шаг подтверждение:
        спросить "Введите количество:" → количество
        если не число(количество):
            ответ "❌ Введите число!"
            повторить шаг
        если количество < 1:
            ответ "❌ Минимум 1 штука!"
            повторить шаг
        ответ "✅ Добавлено в корзину"

# Сценарий поддержки
сценарий поддержка:
    шаг вопрос:
        спросить "Опишите вашу проблему:" → вопрос
        если длина(вопрос) < 10:
            ответ "❌ Описание слишком короткое"
            повторить шаг
        ответ "📨 Ваш вопрос принят! Ответим в течение 24 часов."
        лог "Новый тикет от {пользователь.имя}: {вопрос}"

💡 Примеры

Эхо-бот

бот "ТОКЕН"

при старте:
    ответ "Напишите мне что-нибудь!"

иначе:
    ответ "Вы: " + текст

Бот с меню

бот "ТОКЕН"

при старте:
    ответ "🤖 Главное меню"
    кнопки "Погода" "Новости" "Настройки"

если текст == "Погода":
    ответ "☀️ Сегодня солнечно, +25°C"

если текст == "Новости":
    ответ "📰 Последние новости..."

если текст == "Настройки":
    ответ "⚙️ Настройки профиля"

Бот-опросник

бот "ТОКЕН"

при команде "/опрос":
    запустить опрос

сценарий опрос:
    спросить "Оцените сервис от 1 до 5:" → оценка
    спросить "Что можно улучшить?" → отзыв
    
    ответ "Спасибо за оценку " + оценка + "!"
    ответ "Ваш отзыв: " + отзыв

🛠️ Установка и требования

  • Python: 3.9 или выше
  • Зависимости: requests
  • Токен: Получите у @BotFather в Telegram

📚 Полный справочник команд

Команда Пример Описание
бот бот "TOKEN" Установка токена
при старте: при старте: ответ "Hi" Обработка /start
при команде при команде "/help": Обработка команд
ответ ответ "Текст" + переменная Отправка сообщения
кнопки кнопки "A" "B" "C" Инлайн-кнопки
если если текст == "X": Условие
иначе: иначе: ответ "..." Ветка по умолчанию
сценарий сценарий имя: Объявление FSM
запустить запустить имя Начало сценария
спросить спросить "Вопрос?" → переменная Вопрос пользователю
запомни запомни x = значение Сохранение в память
картинка картинка "url" Отправка фото
стикер стикер "file_id" Отправка стикера
Медиа
документ документ "file.pdf" "Подпись" Отправка файла
аудио аудио "song.mp3" Отправка аудио
видео видео "clip.mp4" Отправка видео
голос голос "voice.ogg" Голосовое сообщение
локация локация 55.75 37.61 Отправка координат
контакт контакт "Имя" "+7999..." Отправка контакта
опрос опрос "Вопрос?" "Да" "Нет" Создание опроса
игра игра "game_short_name" Игра
ответ_md ответ_md "**жирный**" Markdown форматирование
Логика
и если А и Б: Логическое И
или если А или Б: Логическое ИЛИ
не если не А: Отрицание
Строки
содержит() содержит(текст, "X") Проверка подстроки
длина() длина(текст) > 5 Длина строки
начинается_с() начинается_с(текст, "/") Проверка префикса
БД
сохранить сохранить "ключ" = X Сохранить в БД
получить получить "ключ" → перем Загрузить из БД
Получение медиа
при фото: при фото: Обработка фото
при документ: при документ: Обработка файлов
при голос: при голос: Голосовые сообщения
при локации: при локации: Геолокация
при контакте: при контакте: Контакты
FSM
шаг шаг имя: Именованный шаг
завершить завершить сценарий Прервать сценарий
HTTP
http_get http_get "url" → ответ GET-запрос
http_post http_post "url" с "data" → ответ POST-запрос
Кнопки
кнопка кнопка "Текст" -> "callback" Кнопка с callback
кнопка URL кнопка "Сайт" -> url "..." Кнопка с ссылкой
при нажатии при нажатии "buy": Обработчик кнопки
Утилиты
подождать подождать 2 Задержка в секундах
лог лог "сообщение" Вывод в консоль
API
tg tg "sendMessage", {chat_id: чат} Универсальный API
Алиасы
старт: старт: Алиас при старте
команда: команда "/help": Алиас при команде
Импорт
импорт импорт "file.ccd" Подключить файл
импорт пакета импорт "cicada.shop" Импорт пакета
Блоки
блок блок имя: Определить блок
использовать использовать имя Вставить блок
Middleware
до каждого: до каждого: Перед сообщением
после каждого: после каждого: После сообщения
Версия
версия версия "1.0" Версия DSL
Команды меню
команды: команды: "/start" - "Запуск" Меню Telegram
Глобальные
глобально глобально админ = 123 Общая переменная
Контекст
пользователь. пользователь.имя Данные пользователя
чат. чат.id Данные чата
FSM шаги
шаг шаг имя: Именованный шаг
вернуть вернуть Выйти из шага
повторить шаг повторить шаг Повторить текущий
перейти к перейти к шаг имя Перейти к шагу
Валидация
число() если число(возраст): Проверка числа
тип() тип(перем) == "строка" Тип переменной
Типы данных
пусть пусть x = 100 Объявление переменной
истина пусть активен = истина Boolean true
ложь пусть бан = ложь Boolean false
[] пусть товары = ["A", "B"] Массив
Шаблоны
{} "Привет {имя}!" Вставка переменной

Режим разработки: cicada бот.ccd --debug — вывод всех сообщений и ошибок


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

Cicada предоставляет понятные сообщения об ошибках:

Типы ошибок

❌ SyntaxError: Не понимаю условие: 'если текст = "привет"'
              ^
              Ожидалось: '=='

❌ FileNotFoundError: Импорт не найден: helpers.ccd

❌ RuntimeError: Сценарий 'регистрация' не найден

Отладка

# Режим разработки с детальным выводом
cicada bot.ccd --debug

# В выводе:
[DEBUG] Загружен файл: bot.ccd
[DEBUG] Версия DSL: 1.0
[DEBUG] Хендлеров: 5
[DEBUG] Сценариев: 2
[DEBUG]  [123456789] Иван: Привет
[DEBUG]  Ответ: Привет, Иван!

Обработка ошибок в коде

при команде "/risky":
    http_get "https://api.example.com/data" → результат
    если тип(результат) == "строка" и содержит(результат, "Ошибка"):
        ответ "⚠️ API недоступен, попробуйте позже"
    иначе:
        ответ "✅ Данные получены"

⚡ Производительность

Характеристики

Метрика Значение
Пользователей До 10,000 активных
Latency ~100-300ms
Memory ~50-100MB
Storage JSON (легко мигрируется)

Архитектура выполнения

User Message
    ↓
Telegram API (webhook/long polling)
    ↓
Parser (tokenize → AST) ~1-2ms
    ↓
Runtime (user context lookup) ~0.1ms
    ↓
Executor (process statement) ~5-20ms
    ↓
Telegram API (send response) ~50-200ms

Оптимизации

  • Memory-based Runtime — быстрый доступ к контексту пользователя
  • Lazy imports — модули загружаются только при использовании
  • JSON storage — простое и быстрое хранилище
  • Block reuse — блоки кода не дублируются

Масштабирование

Для высоких нагрузок рекомендуется:

# Webhook mode (вместо polling)
export CICADA_MODE=webhook
export CICADA_WEBHOOK_URL=https://your-domain.com/webhook

# Redis для состояния (в планах)
export CICADA_STORAGE=redis
export CICADA_REDIS_URL=redis://localhost:6379

🔒 Безопасность

Встроенная защита

Угроза Защита
Token leak Token в отдельном файле/env
Code injection Sandbox execution, нет eval()
Rate limiting Автоматическая защита от спама
Input validation Валидация всех входных данных
Global state Изоляция пользователей

Best Practices

# Не храните токен в коде
бот getenv("CICADA_TOKEN")  # лучше, чем токен в файле

# Валидация ввода
спросить "Введите сумму:" → сумма
если не число(сумма) или сумма < 0:
    ответ "❌ Некорректная сумма"
    повторить шаг

# Проверка прав
глобально admin_ids = [123456, 789012]
если пользователь.id не в admin_ids:
    ответ "⛔ Нет доступа"
    вернуть

# Логирование действий
лог "Пользователь {пользователь.id} совершил покупку на {сумма}"

Sandbox Execution

  • Нет доступа к файловой системе (кроме db/)
  • Нет сетевых запросов кроме HTTP API
  • Нет импорта Python-модулей
  • Таймауты на HTTP запросы (30 сек)

�� Архитектура проекта (дерево)

cicada/
├── cli.py          # Точка входа (команда cicada)
├── parser.py       # Парсер .ccd → AST
├── executor.py     # Исполнитель AST через Telegram API
├── runner.py       # Загрузчик и оркестратор
├── runtime.py      # Runtime-контекст и память
├── database.py     # JSON-база данных для постоянного хранения
└── adapters/       # Адаптеры API
    └── telegram.py # Telegram Bot API

examples/           # Готовые примеры
    ├── echo.ccd    # Эхо-бот
    ├── shop.ccd    # Магазин
    └── support.ccd # Поддержка

primer.ccd          # Демо-бот
pyproject.toml      # Конфигурация пакета

🤝 Вклад в проект

Баг-репорты, идеи и пул-реквесты приветствуются!

  1. Форкните репозиторий
  2. Создайте ветку: git checkout -b feature/amazing-feature
  3. Закоммитьте: git commit -m 'Add amazing feature'
  4. Пуш: git push origin feature/amazing-feature
  5. Откройте Pull Request

📄 Лицензия

Распространяется под лицензией MIT. См. LICENSE.


🦋 Пишите ботов на родном языке!
Cicada — делайте Telegram-ботов просто

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

cicada_studio-0.0.1.tar.gz (112.8 kB view details)

Uploaded Source

Built Distribution

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

cicada_studio-0.0.1-py3-none-any.whl (94.5 kB view details)

Uploaded Python 3

File details

Details for the file cicada_studio-0.0.1.tar.gz.

File metadata

  • Download URL: cicada_studio-0.0.1.tar.gz
  • Upload date:
  • Size: 112.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for cicada_studio-0.0.1.tar.gz
Algorithm Hash digest
SHA256 f7c97b4e67c3ce0ea21b7238f7116651127e113832dca63156b7e5ab3bbfbf78
MD5 fd61b024f99e067f072862a130ba80a6
BLAKE2b-256 0fca9f36eb9d0b60c888acd82b3302052c3d5da4d43c6a53b82acd23d60eca3a

See more details on using hashes here.

File details

Details for the file cicada_studio-0.0.1-py3-none-any.whl.

File metadata

  • Download URL: cicada_studio-0.0.1-py3-none-any.whl
  • Upload date:
  • Size: 94.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for cicada_studio-0.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 e150a81f12837637d1344d7faa09b7a4546acfd4c48c9dacea4115676eaef462
MD5 1a43fb14a905414456e2696f9c750ce9
BLAKE2b-256 d2fa023807c9c3aff3122dba3051e5ded5a86fda466be0555256c5bfef06352d

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