mirror of
https://gitflic.ru/project/maks1ms/ocab.git
synced 2025-11-28 10:21:55 +03:00
Compare commits
5 Commits
d5f6f1bb4f
...
feat/confi
| Author | SHA1 | Date | |
|---|---|---|---|
| 2becd33774 | |||
| 9fa23f18b9 | |||
| 63b321a500 | |||
| ffa5af740e | |||
| 3130e820c3 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -7,3 +7,4 @@ venv
|
||||
__pycache__
|
||||
OCAB.db
|
||||
config.yaml
|
||||
dist
|
||||
|
||||
80
README.md
80
README.md
@@ -1,60 +1,44 @@
|
||||
# OpenChatAiBot V2
|
||||
# OCAB - Open Chat Ai Bot
|
||||
|
||||
## Что такое OCAB?
|
||||
|
||||
OCAB - это бот для Telegram, который призван помочь во взаимодействии с чатом.
|
||||
Бот поддерживает интеграцию модулей для расширения функционала.
|
||||
Фактически бот является платформой для запуска созданных для него модулей.
|
||||
Модули могут взаимодействовать друг с другом или быть полностью независимыми.
|
||||
OCAB - это платформа для разработки модульных Telegram-ботов, которая призвана упростить взаимодействие с чатами.
|
||||
OCAB предоставляет возможность расширять функциональность бота с помощью интеграции различных модулей.
|
||||
Код платформы и набор стандартных модулей находятся в этом монорепозитории.
|
||||
|
||||
## Что такое модуль?
|
||||
## Структура монорепозитория
|
||||
|
||||
Модуль - это директория, которая содержит в себе код модуля и его конфигурацию.
|
||||
Монорепозиторий OCAB включает в себя:
|
||||
* **Ядро OCAB (src/ocab_core):** Содержит основные компоненты платформы, такие как система управления модулями,
|
||||
логирование и утилиты.
|
||||
* **Модули OCAB (src/ocab_modules):** Содержит стандартные и дополнительные модули, которые расширяют
|
||||
функциональность ботов OCAB.
|
||||
* **Пример бота (src/gnomik):** Пример реализации бота на платформе OCAB.
|
||||
|
||||
## Модули
|
||||
|
||||
Модули OCAB - это независимые компоненты, которые добавляют функциональность к боту.
|
||||
|
||||
### Структура модуля
|
||||
|
||||
*Будет дополнено после закрытия [issue #17](https://gitflic.ru/project/armatik/ocab/issue/17).*
|
||||
Структура модуля представлена [здесь](docs/MODULES-SPEC.md).
|
||||
|
||||
## Стандартные модули
|
||||
### Стандартные модули
|
||||
|
||||
В стандартный состав бота входят следующие модули:
|
||||
Стандартные модули предоставляют базовые функции для работы бота:
|
||||
* [admin](src/ocab_modules/ocab_modules/standard/admin/README.md) - модуль для модерирования чата.
|
||||
* [roles](src/ocab_modules/ocab_modules/standard/roles/README.md) - модуль ролей пользователей.
|
||||
* [config](src/ocab_modules/ocab_modules/standard/config/README.md) - модуль управления конфигурацией бота.
|
||||
* [database](src/ocab_modules/ocab_modules/standard/database/README.md) - модуль для работы с базой данных.
|
||||
* [fsm_database_storage](src/ocab_modules/ocab_modules/standard/fsm_database_storage/README.md) - модуль для хранения состояний FSM в базе данных.
|
||||
* [filters](src/ocab_modules/ocab_modules/standard/filters/README.md) - модуль, предоставляющий фильтры для aiogram.
|
||||
* [message_processing](src/ocab_modules/ocab_modules/standard/message_processing/README.md) - модуль обработки входящих сообщений.
|
||||
* [miniapp](src/ocab_modules/ocab_modules/standard/miniapp/README.md) - модуль для реализации веб-интерфейса бота.
|
||||
* [command_helper](src/ocab_modules/ocab_modules/standard/command_helper/README.md) - модуль для упрощения регистрации команд бота.
|
||||
* [info](src/ocab_modules/ocab_modules/standard/info/README.md) - модуль предоставления информации о пользователях и чатах.
|
||||
|
||||
* `admin` - модуль для модерирования чата. Позволяет удалять сообщения, банить пользователей и т.д.
|
||||
* `reputation` - модуль репутации пользователей. Позволяет оценивать ответы пользователей и накапливать репутацию.
|
||||
* `welcome` - модуль приветствия новых пользователей. Позволяет приветствовать новых пользователей в чате, а также
|
||||
проверять пользователя капчей для предотвращения спама.
|
||||
* `roles` - модуль ролей. Позволяет назначать пользователям роли и ограничивать доступ к командам бота по ролям.
|
||||
Является важной частью системы прав доступа и модуля `admin`.
|
||||
### Дополнительные официальные модули
|
||||
|
||||
## Дополнительные официальные модули
|
||||
|
||||
* `yandexgpt` - модуль для генерации ответов на основе нейросети GPT-3.5. Позволяет боту отвечать на сообщения
|
||||
пользователей, используя нейросеть. Ключевой особенностью является построение линии контекста для нейросети,
|
||||
которая позволяет боту отвечать на вопросы, используя контекст предыдущих сообщений. Для этого используется
|
||||
модуль база данных хранящий историю сообщений.
|
||||
<!--
|
||||
* `bugzilla` - модуль для интеграции с BugZilla. Позволяет получать уведомления о новых багах в BugZilla, отслеживать их
|
||||
статус, формировать стандартизированные сообщения для корректного описания багов. В будущем планируется интеграция с
|
||||
API BugZilla для возможности создания багов из чата.
|
||||
* `alt_packages` - модуль для интеграции с AltLinux Packages. Позволяет получать уведомления о новых пакетах в репозитории
|
||||
AltLinux, поиска пакетов по названию, получения истории изменений, команды для установки пакета из репозитория и
|
||||
прочей информации о пакете.
|
||||
* `notes` - модуль заметок. Позволяет сохранять заметки для пользователей и чатов. Заметки являются ссылками на
|
||||
сообщения в чате.
|
||||
-->
|
||||
|
||||
Список модулей будет пополняться. Идеи для модулей можно оставлять в [issues](https://gitflic.ru/project/armatik/ocab/issue/create).
|
||||
|
||||
## Установка бота
|
||||
|
||||
### Docker
|
||||
|
||||
### Вручную
|
||||
|
||||
## Технологический стек
|
||||
|
||||
* Python 3.11.6 или выше - основной язык программирования.
|
||||
* SQLite 3 - база данных для хранения информации о чате и пользователях.
|
||||
* [Poetry](https://gitflic.ru/project/armatik/ocab/blob?file=how-to%20install%20deps.md&branch=OCAB-V2) - менеджер зависимостей.
|
||||
* aiogram 3 - библиотека для работы с Telegram API.
|
||||
* peewee - ORM для работы с базой данных.
|
||||
Дополнительные официальные модули разработаны командой OCAB и предоставляют расширенные возможности для бота:
|
||||
* [yandexgpt](src/ocab_modules/ocab_modules/external/yandexgpt/README.md) - модуль для интеграции с нейросетью YandexGPT.
|
||||
* [create_report_apps](src/ocab_modules/ocab_modules/external/create_report_apps/README.md) - модуль для создания отчетов об ошибках.
|
||||
|
||||
39
docs/DEV.md
Normal file
39
docs/DEV.md
Normal file
@@ -0,0 +1,39 @@
|
||||
## Настройка рабочего окружения
|
||||
|
||||
Данная инструкция поможет вам настроить рабочее окружение для разработки OCAB.
|
||||
|
||||
### Предварительные требования
|
||||
|
||||
* **Python 3.12:** OCAB требует Python 3.12.
|
||||
* **VSCode:** Рекомендуется использовать VSCode для разработки.
|
||||
* **Git:** У вас должен быть установлен Git для клонирования репозитория.
|
||||
|
||||
### Шаги
|
||||
|
||||
1. **Клонируйте репозиторий:**
|
||||
```bash
|
||||
git clone https://gitflic.ru/project/armatik/ocab.git
|
||||
```
|
||||
|
||||
2. **Откройте проект в VSCode:**
|
||||
* Откройте папку `ocab` в VSCode.
|
||||
* VSCode автоматически предложит открыть проект как workspace, используя файл `ocab.code-workspace`.
|
||||
Нажмите "Открыть Workspace", чтобы принять предложение.
|
||||
|
||||
3. **Настройте Poetry:**
|
||||
* Установите Poetry, следуя инструкциям на официальном сайте: [https://python-poetry.org/docs/](https://python-poetry.org/docs/).
|
||||
* **Для каждого пакета:**
|
||||
* Перейдите в папку пакета (например, `src/ocab_core`).
|
||||
* Выполните команду `poetry install`, чтобы установить зависимости пакета.
|
||||
* Poetry создаст виртуальное окружение внутри папки пакета (`.venv`).
|
||||
|
||||
4. **Активируйте виртуальное окружение:**
|
||||
* Выполните команду `poetry shell` в папке пакета, чтобы активировать виртуальное окружение.
|
||||
|
||||
Теперь ваше рабочее окружение настроено, и вы можете начать.
|
||||
|
||||
### Дополнительная информация
|
||||
|
||||
* Каждый пакет в монорепозитории имеет свой собственный файл `pyproject.toml`, где указаны его зависимости.
|
||||
* Poetry автоматически управляет виртуальными окружениями для каждого пакета.
|
||||
* Вы можете использовать команду `poetry add <package_name>` для добавления новых зависимостей.
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
## Метаинформация о модуле (info.json)
|
||||
|
||||
Этот файл содержит метаинформацию о модуле в формате JSON. Пример структуры info.json приведён ниже:
|
||||
Этот файл содержит метаинформацию о модуле в формате JSON. Пример структуры info.json приведен ниже:
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -20,8 +20,26 @@
|
||||
"version": "1.0.0",
|
||||
"privileged": false,
|
||||
"dependencies": {
|
||||
"required": {
|
||||
"standard.roles": "^1.0.0",
|
||||
"standard.database": "^1.0.0"
|
||||
"standard.database": {
|
||||
"version": "^1.0.0",
|
||||
"uses": [
|
||||
"db_api"
|
||||
]
|
||||
}
|
||||
},
|
||||
"optional": {
|
||||
"external.yandexgpt": "*"
|
||||
}
|
||||
},
|
||||
"pythonDependencies": {
|
||||
"required": {
|
||||
"some_package": "^1.2.3"
|
||||
},
|
||||
"optional": {
|
||||
"another_package": "*"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -30,31 +48,60 @@
|
||||
- `name`: Название модуля.
|
||||
- `description`: Описание функциональности модуля.
|
||||
- `author`: Автор модуля.
|
||||
- `version`: Версия модуля.
|
||||
- `version`: Версия модуля в формате [SemVer](https://semver.org/).
|
||||
- `privileged`: Булево значение, указывающее, является ли модуль привилегированным.
|
||||
- `dependencies`: Объект, описывающий зависимости модуля от других модулей с указанием версии.
|
||||
- `dependencies`: Объект, описывающий зависимости модуля от других **OCAB** модулей.
|
||||
- `required`: Обязательные зависимости. Ключ - идентификатор модуля, значение - версия или объект `DependencyInfo`.
|
||||
- `optional`: Необязательные зависимости. Ключ - идентификатор модуля, значение - версия или объект `DependencyInfo`.
|
||||
- `pythonDependencies`: Объект, описывающий зависимости модуля от внешних Python пакетов.
|
||||
- `required`: Обязательные зависимости. Ключ - название пакета, значение - версия.
|
||||
- `optional`: Необязательные зависимости. Ключ - название пакета, значение - версия.
|
||||
|
||||
### DependencyInfo
|
||||
|
||||
Объект `DependencyInfo` позволяет указать не только версию зависимости, но и список разрешенных к использованию
|
||||
атрибутов модуля (`uses`). Если `uses` не указан, то доступ к модулю целиком запрещен.
|
||||
|
||||
```json
|
||||
{
|
||||
"version": "^1.0.0",
|
||||
"uses": [
|
||||
"db_api"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
- `version`: Версия модуля.
|
||||
- `uses`: Список разрешенных атрибутов модуля.
|
||||
|
||||
## Режимы выполнения модулей
|
||||
|
||||
Непривилегированный режим (`privileged: false`):
|
||||
- Модуль выполняется в доверенной среде на основе RestrictedPython (это накладывает ряд ограничений);
|
||||
- Может использовать только определенный набор разрешенных пакетов
|
||||
**Непривилегированный режим** (`privileged: false`):
|
||||
- Модуль выполняется в доверенной среде на основе RestrictedPython (это накладывает ряд ограничений).
|
||||
- Может импортировать только явно разрешенные модули, указанные в `pythonDependencies`,
|
||||
а также несколько стандартных модулей, необходимых для работы.
|
||||
- Имеет доступ к пакету `ocab_core.modules_system.public_api` для взаимодействия с ботом.
|
||||
|
||||
Привилегированный режим (`privileged: true`):
|
||||
**Привилегированный режим** (`privileged: true`):
|
||||
- Модуль выполняется без ограничений.
|
||||
- Имеет полный доступ ко всем пакетам.
|
||||
- Имеет полный доступ ко всем пакетам, доступным в окружении.
|
||||
- Должен использоваться с осторожностью и только для модулей, требующих расширенных прав.
|
||||
|
||||
## Жизненный цикл модуля
|
||||
|
||||
1. Загрузка метаданных из `info.json`
|
||||
2. Проверка зависимостей
|
||||
3. Загрузка кода модуля из `__init__.py`
|
||||
4. Вызов функции `module_init` (если она есть)
|
||||
1. Загрузка метаданных из `info.json`.
|
||||
2. Проверка зависимостей:
|
||||
- Проверяется наличие всех обязательных зависимостей.
|
||||
- Проверяется совместимость версий зависимостей.
|
||||
- Проверяется наличие Python зависимостей.
|
||||
3. Загрузка кода модуля из `__init__.py`.
|
||||
4. Вызов функции `module_init` (если она есть).
|
||||
5. После загрузки всех модулей вызывается функция `module_late_init` (если она есть).
|
||||
|
||||
## Взаимодействие между модулями
|
||||
|
||||
Модули могут взаимодействовать друг с другом через [API](../src/ocab_core/modules_system/public_api/__init__.py), предоставляемое системой управления модулями.
|
||||
Модули могут взаимодействовать друг с другом через [API](../src/ocab_core/ocab_core/modules_system/public_api/__init__.py),
|
||||
предоставляемое системой управления модулями.
|
||||
|
||||
Например, есть функция `get_module`. Она позволяет получить модуль или предоставляемые им объекты по его идентификатору.
|
||||
Например, есть функция `get_module`. Она позволяет получить модуль или предоставляемые им объекты по его
|
||||
идентификатору.
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
## Poetry
|
||||
|
||||
### Установка с официального сайта
|
||||
|
||||
```shell
|
||||
curl -sSL https://install.python-poetry.org | python3 -
|
||||
```
|
||||
|
||||
### Установка с PyPi
|
||||
|
||||
```shell
|
||||
python3 -m pip install poetry
|
||||
```
|
||||
|
||||
Доп информация:https://www.8host.com/blog/ustanovka-menedzhera-zavisimostej-poetry/
|
||||
|
||||
## Зависимости
|
||||
|
||||
### Добавление зависимости
|
||||
```shell
|
||||
poetry add NAME
|
||||
```
|
||||
`NAME` - название зависимости.
|
||||
|
||||
### Установка зависимостей
|
||||
```shell
|
||||
poetry install
|
||||
```
|
||||
|
||||
### Обновление зависимостей
|
||||
```shell
|
||||
poetry update
|
||||
```
|
||||
|
||||
## Виртуальное окружение
|
||||
|
||||
### Создание/активация
|
||||
```shell
|
||||
poetry shell
|
||||
```
|
||||
|
||||
### Настройка
|
||||
|
||||
Хранить окружение внутри проекта
|
||||
```shell
|
||||
poetry config virtualenvs.in-project true
|
||||
```
|
||||
25
ocab.code-workspace
Normal file
25
ocab.code-workspace
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"folders": [
|
||||
{
|
||||
"name": "OCAB Monorepo Root",
|
||||
"path": ".",
|
||||
},
|
||||
{
|
||||
"name": "OCAB Modules",
|
||||
"path": "src/ocab_modules"
|
||||
},
|
||||
{
|
||||
"name": "OCAB Core",
|
||||
"path": "src/ocab_core"
|
||||
},
|
||||
{
|
||||
"name": "Gnomik",
|
||||
"path": "src/gnomik"
|
||||
}
|
||||
],
|
||||
"extensions": {
|
||||
"recommendations": [
|
||||
"ms-python.python"
|
||||
]
|
||||
},
|
||||
}
|
||||
2
poetry.toml
Normal file
2
poetry.toml
Normal file
@@ -0,0 +1,2 @@
|
||||
[virtualenvs]
|
||||
in-project = true
|
||||
23
src/gnomik/Dockerfile
Normal file
23
src/gnomik/Dockerfile
Normal file
@@ -0,0 +1,23 @@
|
||||
FROM python:3.12-slim as builder
|
||||
|
||||
RUN pip install poetry
|
||||
RUN mkdir -p /app
|
||||
COPY . /app
|
||||
|
||||
# Фикс
|
||||
|
||||
RUN sed -i '/ocab-core = {/{s/, develop = true//}' /app/src/gnomik/pyproject.toml && \
|
||||
sed -i '/ocab-modules = {/{s/, develop = true//}' /app/src/gnomik/pyproject.toml && \
|
||||
sed -i '/ocab-core = {/{s/, develop = true//}' /app/src/ocab_modules/pyproject.toml
|
||||
|
||||
WORKDIR /app/src/gnomik
|
||||
|
||||
RUN poetry lock && poetry install
|
||||
|
||||
FROM python:3.12-slim as base
|
||||
|
||||
COPY --from=builder /app/src/gnomik /app
|
||||
|
||||
WORKDIR /app
|
||||
ENV PATH="/app/.venv/bin:$PATH"
|
||||
CMD ["python", "-m", "gnomik"]
|
||||
14
src/gnomik/Dockerfile.dockerignore
Normal file
14
src/gnomik/Dockerfile.dockerignore
Normal file
@@ -0,0 +1,14 @@
|
||||
**/Dockerfile
|
||||
**/*.dockerignore
|
||||
**/docker-compose.yml
|
||||
|
||||
**/.git
|
||||
**/.gitignore
|
||||
|
||||
**/.venv
|
||||
|
||||
**/.mypy_cache
|
||||
**/__pycache__/
|
||||
|
||||
src/gnomik/config.yaml
|
||||
src/gnomik/database/*
|
||||
@@ -1 +1,55 @@
|
||||
# Гномик
|
||||
# Gnomик
|
||||
|
||||

|
||||
|
||||
Чат-бот помощник в [ALT Gnome Chat](https://t.me/alt_gnome_chat).
|
||||
|
||||
|
||||
ALT Regular Gnome Community - открытое сообщество пользователей операционной системы ALT Regular Gnome.
|
||||
|
||||
- [Канал](https://t.me/alt_gnome)
|
||||
- [Wiki](https://alt-gnome.wiki)
|
||||
|
||||
## Описание
|
||||
|
||||
Gnomик - это чат-бот, разработанный на платформе Open Chat AI Bot (OCAB) для Telegram. Он предоставляет различные функции и возможности, помогающие пользователям операционной системы ALT Regular Gnome.
|
||||
|
||||
## Функционал
|
||||
|
||||
<!--
|
||||
TODO: описать функционал
|
||||
-->
|
||||
|
||||
## Запуск
|
||||
|
||||
### Docker
|
||||
|
||||
1. Соберите Docker-образ:
|
||||
```bash
|
||||
docker build -t gnomik .
|
||||
```
|
||||
2. Запустите контейнер:
|
||||
```bash
|
||||
docker run -p 9000:9000 -v ./config.yaml:/app/config.yaml -v ./database:/app/database gnomik
|
||||
```
|
||||
|
||||
Замените `./config.yaml` и `./database` на пути к вашим локальным файлам конфигурации и паки для базы данных.
|
||||
|
||||
### Вручную
|
||||
|
||||
1. Активируйте виртуальное окружение Gnomика:
|
||||
```bash
|
||||
poetry shell
|
||||
```
|
||||
2. Запустите бота:
|
||||
```bash
|
||||
python -m gnomik
|
||||
```
|
||||
|
||||
## Конфигурация
|
||||
|
||||
Конфигурация бота находится в файле `config.yaml`.
|
||||
|
||||
## Модули
|
||||
|
||||
Список загружаемых модулей указан в файле `__main__.py`.
|
||||
|
||||
18
src/gnomik/config-example.yaml
Normal file
18
src/gnomik/config-example.yaml
Normal file
@@ -0,0 +1,18 @@
|
||||
core:
|
||||
mode: WEBHOOK
|
||||
token: xxx
|
||||
webhook:
|
||||
public_url: xxx
|
||||
filters:
|
||||
approved_chat_id: -4128011756 | -4128011756
|
||||
default_chat_tag: '@alt_gnome_chat'
|
||||
miniapp:
|
||||
public_url: xxx
|
||||
yandexgpt:
|
||||
catalogid: xxx
|
||||
inword: помогите | не работает
|
||||
prompt: Ты чат-бот ...
|
||||
startword: Бот| Бот, | бот | бот,
|
||||
token: xxx
|
||||
token_for_answer: 2000
|
||||
token_for_request: 8000
|
||||
12
src/gnomik/docker-compose.yml
Normal file
12
src/gnomik/docker-compose.yml
Normal file
@@ -0,0 +1,12 @@
|
||||
version: '3'
|
||||
|
||||
services:
|
||||
app:
|
||||
build:
|
||||
context: ../..
|
||||
dockerfile: src/gnomik/Dockerfile
|
||||
ports:
|
||||
- 9000:9000
|
||||
volumes:
|
||||
- ./config.yaml:/app/config.yaml
|
||||
- ./database:/app/database
|
||||
BIN
src/gnomik/docs/gnomik.jpg
Normal file
BIN
src/gnomik/docs/gnomik.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 61 KiB |
@@ -1 +1,23 @@
|
||||
# OCAB Core
|
||||
|
||||
Это ядро OCAB, содержащее базовые компоненты:
|
||||
|
||||
- Система управления модулями.
|
||||
- Логирование.
|
||||
- Утилиты.
|
||||
|
||||
## Система управления модулями
|
||||
|
||||
Система управления модулями отвечает за:
|
||||
|
||||
- Загрузку модулей.
|
||||
- Проверку зависимостей.
|
||||
- Предоставление API для взаимодействия между модулями.
|
||||
|
||||
## Логирование
|
||||
|
||||
Модуль логирования предоставляет функции для записи логов в консоль.
|
||||
|
||||
## Утилиты
|
||||
|
||||
Модуль утилит содержит вспомогательные функции, например, для форматирования текста.
|
||||
|
||||
@@ -78,7 +78,7 @@ class OCAB:
|
||||
singleton = Singleton()
|
||||
app = FastAPI()
|
||||
config = get_module("standard.config", "config")
|
||||
app.mount("/webapp", singleton.storage["webapp"])
|
||||
app.mount(config.get("miniapp::prefix"), singleton.storage["webapp"])
|
||||
await register_bot_webhook(app, singleton.bot, singleton.dp)
|
||||
await singleton.bot.set_webhook(config.get("core::webhook::public_url"))
|
||||
hyperConfig = HyperConfig()
|
||||
|
||||
588
src/ocab_core/poetry.lock
generated
588
src/ocab_core/poetry.lock
generated
@@ -165,7 +165,7 @@ files = [
|
||||
name = "anyio"
|
||||
version = "4.4.0"
|
||||
description = "High level compatibility layer for multiple asynchronous event loop implementations"
|
||||
optional = false
|
||||
optional = true
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "anyio-4.4.0-py3-none-any.whl", hash = "sha256:c1b2d8f46a8a812513012e1107cb0e68c17159a7a594208005a57dc776e1bdc7"},
|
||||
@@ -200,6 +200,28 @@ tests = ["attrs[tests-no-zope]", "zope-interface"]
|
||||
tests-mypy = ["mypy (>=1.6)", "pytest-mypy-plugins"]
|
||||
tests-no-zope = ["attrs[tests-mypy]", "cloudpickle", "hypothesis", "pympler", "pytest (>=4.3.0)", "pytest-xdist[psutil]"]
|
||||
|
||||
[[package]]
|
||||
name = "blinker"
|
||||
version = "1.8.2"
|
||||
description = "Fast, simple object-to-object and broadcast signaling"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "blinker-1.8.2-py3-none-any.whl", hash = "sha256:1779309f71bf239144b9399d06ae925637cf6634cf6bd131104184531bf67c01"},
|
||||
{file = "blinker-1.8.2.tar.gz", hash = "sha256:8f77b09d3bf7c795e969e9486f39c2c5e9c39d4ee07424be2bc594ece9642d83"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cachelib"
|
||||
version = "0.9.0"
|
||||
description = "A collection of cache libraries in the same API interface."
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "cachelib-0.9.0-py3-none-any.whl", hash = "sha256:811ceeb1209d2fe51cd2b62810bd1eccf70feba5c52641532498be5c675493b3"},
|
||||
{file = "cachelib-0.9.0.tar.gz", hash = "sha256:38222cc7c1b79a23606de5c2607f4925779e37cdcea1c2ad21b8bae94b5425a5"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "certifi"
|
||||
version = "2024.7.4"
|
||||
@@ -211,6 +233,105 @@ files = [
|
||||
{file = "certifi-2024.7.4.tar.gz", hash = "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "charset-normalizer"
|
||||
version = "3.3.2"
|
||||
description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
|
||||
optional = false
|
||||
python-versions = ">=3.7.0"
|
||||
files = [
|
||||
{file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"},
|
||||
{file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"},
|
||||
{file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"},
|
||||
{file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"},
|
||||
{file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"},
|
||||
{file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"},
|
||||
{file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"},
|
||||
{file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"},
|
||||
{file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"},
|
||||
{file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"},
|
||||
{file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"},
|
||||
{file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"},
|
||||
{file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"},
|
||||
{file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"},
|
||||
{file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"},
|
||||
{file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"},
|
||||
{file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"},
|
||||
{file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"},
|
||||
{file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"},
|
||||
{file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"},
|
||||
{file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"},
|
||||
{file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"},
|
||||
{file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"},
|
||||
{file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"},
|
||||
{file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"},
|
||||
{file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"},
|
||||
{file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"},
|
||||
{file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"},
|
||||
{file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"},
|
||||
{file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"},
|
||||
{file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"},
|
||||
{file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"},
|
||||
{file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"},
|
||||
{file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"},
|
||||
{file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"},
|
||||
{file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"},
|
||||
{file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"},
|
||||
{file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"},
|
||||
{file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"},
|
||||
{file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"},
|
||||
{file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"},
|
||||
{file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"},
|
||||
{file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"},
|
||||
{file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"},
|
||||
{file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"},
|
||||
{file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"},
|
||||
{file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"},
|
||||
{file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"},
|
||||
{file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"},
|
||||
{file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"},
|
||||
{file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"},
|
||||
{file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"},
|
||||
{file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"},
|
||||
{file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"},
|
||||
{file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"},
|
||||
{file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"},
|
||||
{file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"},
|
||||
{file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"},
|
||||
{file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"},
|
||||
{file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"},
|
||||
{file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"},
|
||||
{file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"},
|
||||
{file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"},
|
||||
{file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"},
|
||||
{file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"},
|
||||
{file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"},
|
||||
{file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"},
|
||||
{file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"},
|
||||
{file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"},
|
||||
{file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"},
|
||||
{file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"},
|
||||
{file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"},
|
||||
{file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"},
|
||||
{file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"},
|
||||
{file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"},
|
||||
{file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"},
|
||||
{file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"},
|
||||
{file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"},
|
||||
{file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"},
|
||||
{file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"},
|
||||
{file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"},
|
||||
{file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"},
|
||||
{file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"},
|
||||
{file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"},
|
||||
{file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"},
|
||||
{file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"},
|
||||
{file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"},
|
||||
{file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"},
|
||||
{file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"},
|
||||
{file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "click"
|
||||
version = "8.1.7"
|
||||
@@ -236,6 +357,128 @@ files = [
|
||||
{file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dash"
|
||||
version = "2.17.1"
|
||||
description = "A Python framework for building reactive web-apps. Developed by Plotly."
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "dash-2.17.1-py3-none-any.whl", hash = "sha256:3eefc9ac67003f93a06bc3e500cae0a6787c48e6c81f6f61514239ae2da414e4"},
|
||||
{file = "dash-2.17.1.tar.gz", hash = "sha256:ee2d9c319de5dcc1314085710b72cd5fa63ff994d913bf72979b7130daeea28e"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
dash-core-components = "2.0.0"
|
||||
dash-html-components = "2.0.0"
|
||||
dash-table = "5.0.0"
|
||||
Flask = ">=1.0.4,<3.1"
|
||||
importlib-metadata = "*"
|
||||
nest-asyncio = "*"
|
||||
plotly = ">=5.0.0"
|
||||
requests = "*"
|
||||
retrying = "*"
|
||||
setuptools = "*"
|
||||
typing-extensions = ">=4.1.1"
|
||||
Werkzeug = "<3.1"
|
||||
|
||||
[package.extras]
|
||||
celery = ["celery[redis] (>=5.1.2)", "redis (>=3.5.3)"]
|
||||
ci = ["black (==22.3.0)", "dash-dangerously-set-inner-html", "dash-flow-example (==0.0.5)", "flake8 (==7.0.0)", "flaky (==3.8.1)", "flask-talisman (==1.0.0)", "jupyterlab (<4.0.0)", "mimesis (<=11.1.0)", "mock (==4.0.3)", "numpy (<=1.26.3)", "openpyxl", "orjson (==3.10.3)", "pandas (>=1.4.0)", "pyarrow", "pylint (==3.0.3)", "pytest-mock", "pytest-rerunfailures", "pytest-sugar (==0.9.6)", "pyzmq (==25.1.2)", "xlrd (>=2.0.1)"]
|
||||
compress = ["flask-compress"]
|
||||
dev = ["PyYAML (>=5.4.1)", "coloredlogs (>=15.0.1)", "fire (>=0.4.0)"]
|
||||
diskcache = ["diskcache (>=5.2.1)", "multiprocess (>=0.70.12)", "psutil (>=5.8.0)"]
|
||||
testing = ["beautifulsoup4 (>=4.8.2)", "cryptography", "dash-testing-stub (>=0.0.2)", "lxml (>=4.6.2)", "multiprocess (>=0.70.12)", "percy (>=2.0.2)", "psutil (>=5.8.0)", "pytest (>=6.0.2)", "requests[security] (>=2.21.0)", "selenium (>=3.141.0,<=4.2.0)", "waitress (>=1.4.4)"]
|
||||
|
||||
[[package]]
|
||||
name = "dash-bootstrap-components"
|
||||
version = "1.6.0"
|
||||
description = "Bootstrap themed components for use in Plotly Dash"
|
||||
optional = false
|
||||
python-versions = "<4,>=3.8"
|
||||
files = [
|
||||
{file = "dash_bootstrap_components-1.6.0-py3-none-any.whl", hash = "sha256:97f0f47b38363f18863e1b247462229266ce12e1e171cfb34d3c9898e6e5cd1e"},
|
||||
{file = "dash_bootstrap_components-1.6.0.tar.gz", hash = "sha256:960a1ec9397574792f49a8241024fa3cecde0f5930c971a3fc81f016cbeb1095"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
dash = ">=2.0.0"
|
||||
|
||||
[package.extras]
|
||||
pandas = ["numpy", "pandas"]
|
||||
|
||||
[[package]]
|
||||
name = "dash-core-components"
|
||||
version = "2.0.0"
|
||||
description = "Core component suite for Dash"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
{file = "dash_core_components-2.0.0-py3-none-any.whl", hash = "sha256:52b8e8cce13b18d0802ee3acbc5e888cb1248a04968f962d63d070400af2e346"},
|
||||
{file = "dash_core_components-2.0.0.tar.gz", hash = "sha256:c6733874af975e552f95a1398a16c2ee7df14ce43fa60bb3718a3c6e0b63ffee"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dash-extensions"
|
||||
version = "1.0.18"
|
||||
description = "Extensions for Plotly Dash."
|
||||
optional = false
|
||||
python-versions = "<4,>=3.9"
|
||||
files = [
|
||||
{file = "dash_extensions-1.0.18-py3-none-any.whl", hash = "sha256:17f4469670bd70ce12fac1a05baaae119fb65eee7b012af47aff7377d0399eeb"},
|
||||
{file = "dash_extensions-1.0.18.tar.gz", hash = "sha256:a6b6c0952b3af7ae84c418fea4b43cbd0bd4e82f20d91f1573380b8a3d90df0a"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
dash = ">=2.17.0"
|
||||
dataclass-wizard = ">=0.22.2,<0.23.0"
|
||||
Flask-Caching = ">=2.1.0,<3.0.0"
|
||||
jsbeautifier = ">=1.14.3,<2.0.0"
|
||||
more-itertools = ">=10.2.0,<11.0.0"
|
||||
pydantic = ">=2.7.1,<3.0.0"
|
||||
ruff = ">=0.4.5,<0.5.0"
|
||||
|
||||
[package.extras]
|
||||
mantine = ["dash-mantine-components (>=0.14.3,<0.15.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "dash-html-components"
|
||||
version = "2.0.0"
|
||||
description = "Vanilla HTML components for Dash"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
{file = "dash_html_components-2.0.0-py3-none-any.whl", hash = "sha256:b42cc903713c9706af03b3f2548bda4be7307a7cf89b7d6eae3da872717d1b63"},
|
||||
{file = "dash_html_components-2.0.0.tar.gz", hash = "sha256:8703a601080f02619a6390998e0b3da4a5daabe97a1fd7a9cebc09d015f26e50"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dash-table"
|
||||
version = "5.0.0"
|
||||
description = "Dash table"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
{file = "dash_table-5.0.0-py3-none-any.whl", hash = "sha256:19036fa352bb1c11baf38068ec62d172f0515f73ca3276c79dee49b95ddc16c9"},
|
||||
{file = "dash_table-5.0.0.tar.gz", hash = "sha256:18624d693d4c8ef2ddec99a6f167593437a7ea0bf153aa20f318c170c5bc7308"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dataclass-wizard"
|
||||
version = "0.22.3"
|
||||
description = "Marshal dataclasses to/from JSON. Use field properties with initial values. Construct a dataclass schema with JSON input."
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
{file = "dataclass-wizard-0.22.3.tar.gz", hash = "sha256:4c46591782265058f1148cfd1f54a3a91221e63986fdd04c9d59f4ced61f4424"},
|
||||
{file = "dataclass_wizard-0.22.3-py2.py3-none-any.whl", hash = "sha256:63751203e54b9b9349212cc185331da73c1adc99c51312575eb73bb5c00c1962"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
dev = ["Sphinx (==5.3.0)", "bump2version (==1.0.1)", "coverage (>=6.2)", "dataclass-factory (==2.12)", "dataclasses-json (==0.5.6)", "flake8 (>=3)", "jsons (==1.6.1)", "pip (>=21.3.1)", "pytest (==7.0.1)", "pytest-cov (==3.0.0)", "pytest-mock (>=3.6.1)", "pytimeparse (==1.1.8)", "sphinx-issues (==3.0.1)", "sphinx-issues (==4.0.0)", "tox (==3.24.5)", "twine (==3.8.0)", "watchdog[watchmedo] (==2.1.6)", "wheel (==0.37.1)", "wheel (==0.42.0)"]
|
||||
timedelta = ["pytimeparse (>=1.1.7)"]
|
||||
yaml = ["PyYAML (>=5.3)"]
|
||||
|
||||
[[package]]
|
||||
name = "dataclasses-json"
|
||||
version = "0.6.7"
|
||||
@@ -255,7 +498,7 @@ typing-inspect = ">=0.4.0,<1"
|
||||
name = "dnspython"
|
||||
version = "2.6.1"
|
||||
description = "DNS toolkit"
|
||||
optional = false
|
||||
optional = true
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "dnspython-2.6.1-py3-none-any.whl", hash = "sha256:5ef3b9680161f6fa89daf8ad451b5f1a33b18ae8a1c6778cdf4b43f08c0a6e50"},
|
||||
@@ -271,11 +514,21 @@ idna = ["idna (>=3.6)"]
|
||||
trio = ["trio (>=0.23)"]
|
||||
wmi = ["wmi (>=1.5.1)"]
|
||||
|
||||
[[package]]
|
||||
name = "editorconfig"
|
||||
version = "0.12.4"
|
||||
description = "EditorConfig File Locator and Interpreter for Python"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
{file = "EditorConfig-0.12.4.tar.gz", hash = "sha256:24857fa1793917dd9ccf0c7810a07e05404ce9b823521c7dce22a4fb5d125f80"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "email-validator"
|
||||
version = "2.2.0"
|
||||
description = "A robust email address syntax and deliverability validation library."
|
||||
optional = false
|
||||
optional = true
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "email_validator-2.2.0-py3-none-any.whl", hash = "sha256:561977c2d73ce3611850a06fa56b414621e0c8faa9d66f2611407d87465da631"},
|
||||
@@ -290,7 +543,7 @@ idna = ">=2.0.0"
|
||||
name = "fastapi"
|
||||
version = "0.111.1"
|
||||
description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production"
|
||||
optional = false
|
||||
optional = true
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "fastapi-0.111.1-py3-none-any.whl", hash = "sha256:4f51cfa25d72f9fbc3280832e84b32494cf186f50158d364a8765aabf22587bf"},
|
||||
@@ -315,7 +568,7 @@ all = ["email_validator (>=2.0.0)", "httpx (>=0.23.0)", "itsdangerous (>=1.1.0)"
|
||||
name = "fastapi-cli"
|
||||
version = "0.0.4"
|
||||
description = "Run and manage FastAPI apps from the command line with FastAPI CLI. 🚀"
|
||||
optional = false
|
||||
optional = true
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "fastapi_cli-0.0.4-py3-none-any.whl", hash = "sha256:a2552f3a7ae64058cdbb530be6fa6dbfc975dc165e4fa66d224c3d396e25e809"},
|
||||
@@ -328,6 +581,43 @@ typer = ">=0.12.3"
|
||||
[package.extras]
|
||||
standard = ["fastapi", "uvicorn[standard] (>=0.15.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "flask"
|
||||
version = "3.0.3"
|
||||
description = "A simple framework for building complex web applications."
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "flask-3.0.3-py3-none-any.whl", hash = "sha256:34e815dfaa43340d1d15a5c3a02b8476004037eb4840b34910c6e21679d288f3"},
|
||||
{file = "flask-3.0.3.tar.gz", hash = "sha256:ceb27b0af3823ea2737928a4d99d125a06175b8512c445cbd9a9ce200ef76842"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
blinker = ">=1.6.2"
|
||||
click = ">=8.1.3"
|
||||
itsdangerous = ">=2.1.2"
|
||||
Jinja2 = ">=3.1.2"
|
||||
Werkzeug = ">=3.0.0"
|
||||
|
||||
[package.extras]
|
||||
async = ["asgiref (>=3.2)"]
|
||||
dotenv = ["python-dotenv"]
|
||||
|
||||
[[package]]
|
||||
name = "flask-caching"
|
||||
version = "2.3.0"
|
||||
description = "Adds caching support to Flask applications."
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "Flask_Caching-2.3.0-py3-none-any.whl", hash = "sha256:51771c75682e5abc1483b78b96d9131d7941dc669b073852edfa319dd4e29b6e"},
|
||||
{file = "flask_caching-2.3.0.tar.gz", hash = "sha256:d7e4ca64a33b49feb339fcdd17e6ba25f5e01168cf885e53790e885f83a4d2cf"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
cachelib = ">=0.9.0,<0.10.0"
|
||||
Flask = "*"
|
||||
|
||||
[[package]]
|
||||
name = "frozenlist"
|
||||
version = "1.4.1"
|
||||
@@ -418,7 +708,7 @@ files = [
|
||||
name = "h11"
|
||||
version = "0.14.0"
|
||||
description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1"
|
||||
optional = false
|
||||
optional = true
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"},
|
||||
@@ -429,7 +719,7 @@ files = [
|
||||
name = "h2"
|
||||
version = "4.1.0"
|
||||
description = "HTTP/2 State-Machine based protocol implementation"
|
||||
optional = false
|
||||
optional = true
|
||||
python-versions = ">=3.6.1"
|
||||
files = [
|
||||
{file = "h2-4.1.0-py3-none-any.whl", hash = "sha256:03a46bcf682256c95b5fd9e9a99c1323584c3eec6440d379b9903d709476bc6d"},
|
||||
@@ -444,7 +734,7 @@ hyperframe = ">=6.0,<7"
|
||||
name = "hpack"
|
||||
version = "4.0.0"
|
||||
description = "Pure-Python HPACK header compression"
|
||||
optional = false
|
||||
optional = true
|
||||
python-versions = ">=3.6.1"
|
||||
files = [
|
||||
{file = "hpack-4.0.0-py3-none-any.whl", hash = "sha256:84a076fad3dc9a9f8063ccb8041ef100867b1878b25ef0ee63847a5d53818a6c"},
|
||||
@@ -455,7 +745,7 @@ files = [
|
||||
name = "httpcore"
|
||||
version = "1.0.5"
|
||||
description = "A minimal low-level HTTP client."
|
||||
optional = false
|
||||
optional = true
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "httpcore-1.0.5-py3-none-any.whl", hash = "sha256:421f18bac248b25d310f3cacd198d55b8e6125c107797b609ff9b7a6ba7991b5"},
|
||||
@@ -476,7 +766,7 @@ trio = ["trio (>=0.22.0,<0.26.0)"]
|
||||
name = "httptools"
|
||||
version = "0.6.1"
|
||||
description = "A collection of framework independent HTTP protocol utils."
|
||||
optional = false
|
||||
optional = true
|
||||
python-versions = ">=3.8.0"
|
||||
files = [
|
||||
{file = "httptools-0.6.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d2f6c3c4cb1948d912538217838f6e9960bc4a521d7f9b323b3da579cd14532f"},
|
||||
@@ -524,7 +814,7 @@ test = ["Cython (>=0.29.24,<0.30.0)"]
|
||||
name = "httpx"
|
||||
version = "0.27.0"
|
||||
description = "The next generation HTTP client."
|
||||
optional = false
|
||||
optional = true
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "httpx-0.27.0-py3-none-any.whl", hash = "sha256:71d5465162c13681bff01ad59b2cc68dd838ea1f10e51574bac27103f00c91a5"},
|
||||
@@ -548,7 +838,7 @@ socks = ["socksio (==1.*)"]
|
||||
name = "hypercorn"
|
||||
version = "0.17.3"
|
||||
description = "A ASGI Server based on Hyper libraries and inspired by Gunicorn"
|
||||
optional = false
|
||||
optional = true
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "hypercorn-0.17.3-py3-none-any.whl", hash = "sha256:059215dec34537f9d40a69258d323f56344805efb462959e727152b0aa504547"},
|
||||
@@ -571,7 +861,7 @@ uvloop = ["uvloop (>=0.18)"]
|
||||
name = "hyperframe"
|
||||
version = "6.0.1"
|
||||
description = "HTTP/2 framing layer for Python"
|
||||
optional = false
|
||||
optional = true
|
||||
python-versions = ">=3.6.1"
|
||||
files = [
|
||||
{file = "hyperframe-6.0.1-py3-none-any.whl", hash = "sha256:0ec6bafd80d8ad2195c4f03aacba3a8265e57bc4cff261e802bf39970ed02a15"},
|
||||
@@ -589,6 +879,36 @@ files = [
|
||||
{file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "importlib-metadata"
|
||||
version = "8.2.0"
|
||||
description = "Read metadata from Python packages"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "importlib_metadata-8.2.0-py3-none-any.whl", hash = "sha256:11901fa0c2f97919b288679932bb64febaeacf289d18ac84dd68cb2e74213369"},
|
||||
{file = "importlib_metadata-8.2.0.tar.gz", hash = "sha256:72e8d4399996132204f9a16dcc751af254a48f8d1b20b9ff0f98d4a8f901e73d"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
zipp = ">=0.5"
|
||||
|
||||
[package.extras]
|
||||
doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
|
||||
perf = ["ipython"]
|
||||
test = ["flufl.flake8", "importlib-resources (>=1.3)", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-perf (>=0.9.2)", "pytest-ruff (>=0.2.1)"]
|
||||
|
||||
[[package]]
|
||||
name = "itsdangerous"
|
||||
version = "2.2.0"
|
||||
description = "Safely pass data to untrusted environments and back."
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "itsdangerous-2.2.0-py3-none-any.whl", hash = "sha256:c6242fc49e35958c8b15141343aa660db5fc54d4f13a1db01a3f5891b98700ef"},
|
||||
{file = "itsdangerous-2.2.0.tar.gz", hash = "sha256:e0050c0b7da1eea53ffaf149c0cfbb5c6e2e2b69c4bef22c81fa6eb73e5f6173"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jinja2"
|
||||
version = "3.1.4"
|
||||
@@ -606,6 +926,20 @@ MarkupSafe = ">=2.0"
|
||||
[package.extras]
|
||||
i18n = ["Babel (>=2.7)"]
|
||||
|
||||
[[package]]
|
||||
name = "jsbeautifier"
|
||||
version = "1.15.1"
|
||||
description = "JavaScript unobfuscator and beautifier."
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
{file = "jsbeautifier-1.15.1.tar.gz", hash = "sha256:ebd733b560704c602d744eafc839db60a1ee9326e30a2a80c4adb8718adc1b24"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
editorconfig = ">=0.12.2"
|
||||
six = ">=1.13.0"
|
||||
|
||||
[[package]]
|
||||
name = "magic-filter"
|
||||
version = "1.0.12"
|
||||
@@ -624,7 +958,7 @@ dev = ["black (>=22.8.0,<22.9.0)", "flake8 (>=5.0.4,<5.1.0)", "isort (>=5.11.5,<
|
||||
name = "markdown-it-py"
|
||||
version = "3.0.0"
|
||||
description = "Python port of markdown-it. Markdown parsing, done right!"
|
||||
optional = false
|
||||
optional = true
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb"},
|
||||
@@ -736,13 +1070,24 @@ tests = ["pytest", "pytz", "simplejson"]
|
||||
name = "mdurl"
|
||||
version = "0.1.2"
|
||||
description = "Markdown URL utilities"
|
||||
optional = false
|
||||
optional = true
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"},
|
||||
{file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "more-itertools"
|
||||
version = "10.3.0"
|
||||
description = "More routines for operating on iterables, beyond itertools"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "more-itertools-10.3.0.tar.gz", hash = "sha256:e5d93ef411224fbcef366a6e8ddc4c5781bc6359d43412a65dd5964e46111463"},
|
||||
{file = "more_itertools-10.3.0-py3-none-any.whl", hash = "sha256:ea6a02e24a9161e51faad17a8782b92a0df82c12c1c8886fec7f0c3fa1a1b320"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "multidict"
|
||||
version = "6.0.5"
|
||||
@@ -853,6 +1198,17 @@ files = [
|
||||
{file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nest-asyncio"
|
||||
version = "1.6.0"
|
||||
description = "Patch asyncio to allow nested event loops"
|
||||
optional = false
|
||||
python-versions = ">=3.5"
|
||||
files = [
|
||||
{file = "nest_asyncio-1.6.0-py3-none-any.whl", hash = "sha256:87af6efd6b5e897c81050477ef65c62e2b2f35d51703cae01aff2905b1852e1c"},
|
||||
{file = "nest_asyncio-1.6.0.tar.gz", hash = "sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ocab-modules"
|
||||
version = "0.1.0"
|
||||
@@ -862,6 +1218,14 @@ python-versions = "~3.12"
|
||||
files = []
|
||||
develop = true
|
||||
|
||||
[package.dependencies]
|
||||
dash = "^2.17.1"
|
||||
dash-bootstrap-components = "^1.6.0"
|
||||
dash-extensions = "^1.0.18"
|
||||
ocab-core = {path = "../ocab_core", develop = true}
|
||||
peewee = "^3.17.6"
|
||||
pyyaml = "^6.0.1"
|
||||
|
||||
[package.source]
|
||||
type = "directory"
|
||||
url = "../ocab_modules"
|
||||
@@ -877,11 +1241,36 @@ files = [
|
||||
{file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "peewee"
|
||||
version = "3.17.6"
|
||||
description = "a little orm"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
{file = "peewee-3.17.6.tar.gz", hash = "sha256:cea5592c6f4da1592b7cff8eaf655be6648a1f5857469e30037bf920c03fb8fb"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "plotly"
|
||||
version = "5.23.0"
|
||||
description = "An open-source, interactive data visualization library for Python"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "plotly-5.23.0-py3-none-any.whl", hash = "sha256:76cbe78f75eddc10c56f5a4ee3e7ccaade7c0a57465546f02098c0caed6c2d1a"},
|
||||
{file = "plotly-5.23.0.tar.gz", hash = "sha256:89e57d003a116303a34de6700862391367dd564222ab71f8531df70279fc0193"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
packaging = "*"
|
||||
tenacity = ">=6.2.0"
|
||||
|
||||
[[package]]
|
||||
name = "priority"
|
||||
version = "2.0.0"
|
||||
description = "A pure-Python implementation of the HTTP/2 priority tree"
|
||||
optional = false
|
||||
optional = true
|
||||
python-versions = ">=3.6.1"
|
||||
files = [
|
||||
{file = "priority-2.0.0-py3-none-any.whl", hash = "sha256:6f8eefce5f3ad59baf2c080a664037bb4725cd0a790d53d59ab4059288faf6aa"},
|
||||
@@ -1012,7 +1401,7 @@ typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0"
|
||||
name = "pygments"
|
||||
version = "2.18.0"
|
||||
description = "Pygments is a syntax highlighting package written in Python."
|
||||
optional = false
|
||||
optional = true
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "pygments-2.18.0-py3-none-any.whl", hash = "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a"},
|
||||
@@ -1026,7 +1415,7 @@ windows-terminal = ["colorama (>=0.4.6)"]
|
||||
name = "python-dotenv"
|
||||
version = "1.0.1"
|
||||
description = "Read key-value pairs from a .env file and set them as environment variables"
|
||||
optional = false
|
||||
optional = true
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "python-dotenv-1.0.1.tar.gz", hash = "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca"},
|
||||
@@ -1040,7 +1429,7 @@ cli = ["click (>=5.0)"]
|
||||
name = "python-multipart"
|
||||
version = "0.0.9"
|
||||
description = "A streaming multipart parser for Python"
|
||||
optional = false
|
||||
optional = true
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "python_multipart-0.0.9-py3-none-any.whl", hash = "sha256:97ca7b8ea7b05f977dc3849c3ba99d51689822fab725c3703af7c866a0c2b215"},
|
||||
@@ -1110,6 +1499,27 @@ files = [
|
||||
{file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "requests"
|
||||
version = "2.32.3"
|
||||
description = "Python HTTP for Humans."
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"},
|
||||
{file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
certifi = ">=2017.4.17"
|
||||
charset-normalizer = ">=2,<4"
|
||||
idna = ">=2.5,<4"
|
||||
urllib3 = ">=1.21.1,<3"
|
||||
|
||||
[package.extras]
|
||||
socks = ["PySocks (>=1.5.6,!=1.5.7)"]
|
||||
use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"]
|
||||
|
||||
[[package]]
|
||||
name = "restrictedpython"
|
||||
version = "7.1"
|
||||
@@ -1125,11 +1535,25 @@ files = [
|
||||
docs = ["Sphinx", "sphinx-rtd-theme"]
|
||||
test = ["pytest", "pytest-mock"]
|
||||
|
||||
[[package]]
|
||||
name = "retrying"
|
||||
version = "1.3.4"
|
||||
description = "Retrying"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
{file = "retrying-1.3.4-py3-none-any.whl", hash = "sha256:8cc4d43cb8e1125e0ff3344e9de678fefd85db3b750b81b2240dc0183af37b35"},
|
||||
{file = "retrying-1.3.4.tar.gz", hash = "sha256:345da8c5765bd982b1d1915deb9102fd3d1f7ad16bd84a9700b85f64d24e8f3e"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
six = ">=1.7.0"
|
||||
|
||||
[[package]]
|
||||
name = "rich"
|
||||
version = "13.7.1"
|
||||
description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal"
|
||||
optional = false
|
||||
optional = true
|
||||
python-versions = ">=3.7.0"
|
||||
files = [
|
||||
{file = "rich-13.7.1-py3-none-any.whl", hash = "sha256:4edbae314f59eb482f54e9e30bf00d33350aaa94f4bfcd4e9e3110e64d0d7222"},
|
||||
@@ -1143,6 +1567,32 @@ pygments = ">=2.13.0,<3.0.0"
|
||||
[package.extras]
|
||||
jupyter = ["ipywidgets (>=7.5.1,<9)"]
|
||||
|
||||
[[package]]
|
||||
name = "ruff"
|
||||
version = "0.4.10"
|
||||
description = "An extremely fast Python linter and code formatter, written in Rust."
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "ruff-0.4.10-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:5c2c4d0859305ac5a16310eec40e4e9a9dec5dcdfbe92697acd99624e8638dac"},
|
||||
{file = "ruff-0.4.10-py3-none-macosx_11_0_arm64.whl", hash = "sha256:a79489607d1495685cdd911a323a35871abfb7a95d4f98fc6f85e799227ac46e"},
|
||||
{file = "ruff-0.4.10-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1dd1681dfa90a41b8376a61af05cc4dc5ff32c8f14f5fe20dba9ff5deb80cd6"},
|
||||
{file = "ruff-0.4.10-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c75c53bb79d71310dc79fb69eb4902fba804a81f374bc86a9b117a8d077a1784"},
|
||||
{file = "ruff-0.4.10-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:18238c80ee3d9100d3535d8eb15a59c4a0753b45cc55f8bf38f38d6a597b9739"},
|
||||
{file = "ruff-0.4.10-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:d8f71885bce242da344989cae08e263de29752f094233f932d4f5cfb4ef36a81"},
|
||||
{file = "ruff-0.4.10-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:330421543bd3222cdfec481e8ff3460e8702ed1e58b494cf9d9e4bf90db52b9d"},
|
||||
{file = "ruff-0.4.10-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9e9b6fb3a37b772628415b00c4fc892f97954275394ed611056a4b8a2631365e"},
|
||||
{file = "ruff-0.4.10-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f54c481b39a762d48f64d97351048e842861c6662d63ec599f67d515cb417f6"},
|
||||
{file = "ruff-0.4.10-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:67fe086b433b965c22de0b4259ddfe6fa541c95bf418499bedb9ad5fb8d1c631"},
|
||||
{file = "ruff-0.4.10-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:acfaaab59543382085f9eb51f8e87bac26bf96b164839955f244d07125a982ef"},
|
||||
{file = "ruff-0.4.10-py3-none-musllinux_1_2_i686.whl", hash = "sha256:3cea07079962b2941244191569cf3a05541477286f5cafea638cd3aa94b56815"},
|
||||
{file = "ruff-0.4.10-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:338a64ef0748f8c3a80d7f05785930f7965d71ca260904a9321d13be24b79695"},
|
||||
{file = "ruff-0.4.10-py3-none-win32.whl", hash = "sha256:ffe3cd2f89cb54561c62e5fa20e8f182c0a444934bf430515a4b422f1ab7b7ca"},
|
||||
{file = "ruff-0.4.10-py3-none-win_amd64.whl", hash = "sha256:67f67cef43c55ffc8cc59e8e0b97e9e60b4837c8f21e8ab5ffd5d66e196e25f7"},
|
||||
{file = "ruff-0.4.10-py3-none-win_arm64.whl", hash = "sha256:dd1fcee327c20addac7916ca4e2653fbbf2e8388d8a6477ce5b4e986b68ae6c0"},
|
||||
{file = "ruff-0.4.10.tar.gz", hash = "sha256:3aa4f2bc388a30d346c56524f7cacca85945ba124945fe489952aadb6b5cd804"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "3.0.2"
|
||||
@@ -1174,18 +1624,29 @@ test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata
|
||||
name = "shellingham"
|
||||
version = "1.5.4"
|
||||
description = "Tool to Detect Surrounding Shell"
|
||||
optional = false
|
||||
optional = true
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686"},
|
||||
{file = "shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "six"
|
||||
version = "1.16.0"
|
||||
description = "Python 2 and 3 compatibility utilities"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
|
||||
files = [
|
||||
{file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
|
||||
{file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sniffio"
|
||||
version = "1.3.1"
|
||||
description = "Sniff out which async library your code is running under"
|
||||
optional = false
|
||||
optional = true
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2"},
|
||||
@@ -1196,7 +1657,7 @@ files = [
|
||||
name = "starlette"
|
||||
version = "0.37.2"
|
||||
description = "The little ASGI library that shines."
|
||||
optional = false
|
||||
optional = true
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "starlette-0.37.2-py3-none-any.whl", hash = "sha256:6fe59f29268538e5d0d182f2791a479a0c64638e6935d1c6989e63fb2699c6ee"},
|
||||
@@ -1209,11 +1670,26 @@ anyio = ">=3.4.0,<5"
|
||||
[package.extras]
|
||||
full = ["httpx (>=0.22.0)", "itsdangerous", "jinja2", "python-multipart (>=0.0.7)", "pyyaml"]
|
||||
|
||||
[[package]]
|
||||
name = "tenacity"
|
||||
version = "9.0.0"
|
||||
description = "Retry code until it succeeds"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "tenacity-9.0.0-py3-none-any.whl", hash = "sha256:93de0c98785b27fcf659856aa9f54bfbd399e29969b0621bc7f762bd441b4539"},
|
||||
{file = "tenacity-9.0.0.tar.gz", hash = "sha256:807f37ca97d62aa361264d497b0e31e92b8027044942bfa756160d908320d73b"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
doc = ["reno", "sphinx"]
|
||||
test = ["pytest", "tornado (>=4.5)", "typeguard"]
|
||||
|
||||
[[package]]
|
||||
name = "typer"
|
||||
version = "0.12.3"
|
||||
description = "Typer, build great CLIs. Easy to code. Based on Python type hints."
|
||||
optional = false
|
||||
optional = true
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "typer-0.12.3-py3-none-any.whl", hash = "sha256:070d7ca53f785acbccba8e7d28b08dcd88f79f1fbda035ade0aecec71ca5c914"},
|
||||
@@ -1252,11 +1728,28 @@ files = [
|
||||
mypy-extensions = ">=0.3.0"
|
||||
typing-extensions = ">=3.7.4"
|
||||
|
||||
[[package]]
|
||||
name = "urllib3"
|
||||
version = "2.2.2"
|
||||
description = "HTTP library with thread-safe connection pooling, file post, and more."
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "urllib3-2.2.2-py3-none-any.whl", hash = "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472"},
|
||||
{file = "urllib3-2.2.2.tar.gz", hash = "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"]
|
||||
h2 = ["h2 (>=4,<5)"]
|
||||
socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"]
|
||||
zstd = ["zstandard (>=0.18.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "uvicorn"
|
||||
version = "0.30.3"
|
||||
description = "The lightning-fast ASGI server."
|
||||
optional = false
|
||||
optional = true
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "uvicorn-0.30.3-py3-none-any.whl", hash = "sha256:94a3608da0e530cea8f69683aa4126364ac18e3826b6630d1a65f4638aade503"},
|
||||
@@ -1281,7 +1774,7 @@ standard = ["colorama (>=0.4)", "httptools (>=0.5.0)", "python-dotenv (>=0.13)",
|
||||
name = "uvloop"
|
||||
version = "0.19.0"
|
||||
description = "Fast implementation of asyncio event loop on top of libuv"
|
||||
optional = false
|
||||
optional = true
|
||||
python-versions = ">=3.8.0"
|
||||
files = [
|
||||
{file = "uvloop-0.19.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:de4313d7f575474c8f5a12e163f6d89c0a878bc49219641d49e6f1444369a90e"},
|
||||
@@ -1325,7 +1818,7 @@ test = ["Cython (>=0.29.36,<0.30.0)", "aiohttp (==3.9.0b0)", "aiohttp (>=3.8.1)"
|
||||
name = "watchfiles"
|
||||
version = "0.22.0"
|
||||
description = "Simple, modern and high performance file watching and code reload in python."
|
||||
optional = false
|
||||
optional = true
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "watchfiles-0.22.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:da1e0a8caebf17976e2ffd00fa15f258e14749db5e014660f53114b676e68538"},
|
||||
@@ -1412,7 +1905,7 @@ anyio = ">=3.0.0"
|
||||
name = "websockets"
|
||||
version = "12.0"
|
||||
description = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)"
|
||||
optional = false
|
||||
optional = true
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "websockets-12.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d554236b2a2006e0ce16315c16eaa0d628dab009c33b63ea03f41c6107958374"},
|
||||
@@ -1489,11 +1982,28 @@ files = [
|
||||
{file = "websockets-12.0.tar.gz", hash = "sha256:81df9cbcbb6c260de1e007e58c011bfebe2dafc8435107b0537f393dd38c8b1b"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "werkzeug"
|
||||
version = "3.0.3"
|
||||
description = "The comprehensive WSGI web application library."
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "werkzeug-3.0.3-py3-none-any.whl", hash = "sha256:fc9645dc43e03e4d630d23143a04a7f947a9a3b5727cd535fdfe155a17cc48c8"},
|
||||
{file = "werkzeug-3.0.3.tar.gz", hash = "sha256:097e5bfda9f0aba8da6b8545146def481d06aa7d3266e7448e2cccf67dd8bd18"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
MarkupSafe = ">=2.1.1"
|
||||
|
||||
[package.extras]
|
||||
watchdog = ["watchdog (>=2.3)"]
|
||||
|
||||
[[package]]
|
||||
name = "wsproto"
|
||||
version = "1.2.0"
|
||||
description = "WebSockets state-machine based protocol implementation"
|
||||
optional = false
|
||||
optional = true
|
||||
python-versions = ">=3.7.0"
|
||||
files = [
|
||||
{file = "wsproto-1.2.0-py3-none-any.whl", hash = "sha256:b9acddd652b585d75b20477888c56642fdade28bdfd3579aa24a4d2c037dd736"},
|
||||
@@ -1606,7 +2116,25 @@ files = [
|
||||
idna = ">=2.0"
|
||||
multidict = ">=4.0"
|
||||
|
||||
[[package]]
|
||||
name = "zipp"
|
||||
version = "3.19.2"
|
||||
description = "Backport of pathlib-compatible object wrapper for zip files"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "zipp-3.19.2-py3-none-any.whl", hash = "sha256:f091755f667055f2d02b32c53771a7a6c8b47e1fdbc4b72a8b9072b3eef8015c"},
|
||||
{file = "zipp-3.19.2.tar.gz", hash = "sha256:bf1dcf6450f873a13e952a29504887c89e6de7506209e5b1bcc3460135d4de19"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
|
||||
test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy", "pytest-ruff (>=0.2.1)"]
|
||||
|
||||
[extras]
|
||||
webhook = ["fastapi", "hypercorn"]
|
||||
|
||||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = "~3.12"
|
||||
content-hash = "d0a976df8c14926cacbc93eda55b49eee73eeaa4fc66a9a1a6fd86f3d8f0db64"
|
||||
content-hash = "374abe60f0df5be4f88b1b0aeefe73b4205ff2a08625359e8191dae5795d5c8f"
|
||||
|
||||
@@ -1 +1,12 @@
|
||||
# OCAB Modules
|
||||
|
||||
OCAB Modules содержит набор модулей для платформы Open Chat AI Bot (OCAB).
|
||||
|
||||
## Описание
|
||||
|
||||
OCAB - это платформа для создания чат-ботов Telegram. Модули - это расширения, которые добавляют функциональность ботам OCAB.
|
||||
|
||||
## Типы модулей
|
||||
|
||||
* **Стандартные модули (standard.*):** Предоставляют основные функции, такие как управление пользователями, ролями и настройками.
|
||||
* **Дополнительные официальные модули (external.*):** Разработаны командой OCAB и предоставляют расширенные возможности, такие как интеграция с нейросетями, внешними сервисами и API.
|
||||
|
||||
19
src/ocab_modules/ocab_modules/external/create_report_apps/README.md
vendored
Normal file
19
src/ocab_modules/ocab_modules/external/create_report_apps/README.md
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
# Модуль Create Report Apps
|
||||
|
||||
Модуль `create_report_apps` предназначен для помощи пользователям в создании отчетов об ошибках в приложениях.
|
||||
|
||||
## Функциональность
|
||||
|
||||
- Задает пользователю ряд вопросов, необходимых для составления отчета.
|
||||
- Собирает информацию о системе пользователя.
|
||||
- Формирует отчет в текстовом формате.
|
||||
|
||||
## Команды
|
||||
|
||||
- `/create_report_apps` - запустить процесс создания отчета.
|
||||
|
||||
## Использование
|
||||
|
||||
1. Отправьте команду `/create_report_apps` боту в личных сообщениях или в групповом чате.
|
||||
2. Ответьте на вопросы бота.
|
||||
3. Бот сформирует отчет и отправит его вам.
|
||||
22
src/ocab_modules/ocab_modules/external/yandexgpt/README.md
vendored
Normal file
22
src/ocab_modules/ocab_modules/external/yandexgpt/README.md
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
# Модуль YandexGPT
|
||||
|
||||
Модуль `yandexgpt` интегрирует в бота OCAB нейросеть YandexGPT.
|
||||
|
||||
## Функциональность
|
||||
|
||||
- Позволяет боту отвечать на сообщения пользователей, используя YandexGPT.
|
||||
- Строит линию контекста для нейросети, используя историю сообщений.
|
||||
|
||||
## Конфигурация
|
||||
|
||||
- `yandexgpt::token` - API-ключ для доступа к YandexGPT.
|
||||
- `yandexgpt::catalogid` - идентификатор каталога YandexGPT.
|
||||
- `yandexgpt::prompt` - системная подсказка для YandexGPT.
|
||||
- `yandexgpt::startword` - слова, с которых должно начинаться сообщение, чтобы бот ответил.
|
||||
- `yandexgpt::inword` - слова, которые должны быть в сообщении, чтобы бот ответил.
|
||||
|
||||
## Использование
|
||||
|
||||
1. Настройте конфигурационные параметры модуля.
|
||||
2. Отправьте боту сообщение, которое соответствует условиям, указанным в параметрах `startword` и `inword`.
|
||||
3. Бот ответит на сообщение, используя YandexGPT.
|
||||
20
src/ocab_modules/ocab_modules/standard/admin/README.md
Normal file
20
src/ocab_modules/ocab_modules/standard/admin/README.md
Normal file
@@ -0,0 +1,20 @@
|
||||
# Модуль Admin
|
||||
|
||||
Модуль `admin` предоставляет администраторам и модераторам чата инструменты для управления:
|
||||
|
||||
## Функциональность
|
||||
|
||||
- Удаление сообщений.
|
||||
- Получение ID чата.
|
||||
|
||||
## Команды
|
||||
|
||||
- `/rm` - удалить сообщение, на которое отвечает команда.
|
||||
- `/chatID` - получить ID текущего чата.
|
||||
|
||||
## Использование
|
||||
|
||||
1. Ответьте на сообщение, которое нужно удалить.
|
||||
2. Отправьте команду `/rm`.
|
||||
|
||||
Чтобы получить ID чата, отправьте команду `/chatID`.
|
||||
@@ -0,0 +1,24 @@
|
||||
# Модуль Command Helper
|
||||
|
||||
Модуль `command_helper` упрощает регистрацию команд бота и управление ими.
|
||||
|
||||
## Функциональность
|
||||
|
||||
- Регистрация команд бота.
|
||||
- Установка команд для пользователей в зависимости от их роли.
|
||||
|
||||
## Использование
|
||||
|
||||
1. Импортируйте функцию `register_command`.
|
||||
2. Вызовите функцию `register_command`, передав ей название команды, ее описание и роль пользователя,
|
||||
которому доступна эта команда.
|
||||
|
||||
## Пример
|
||||
|
||||
```python
|
||||
from ocab_core.modules_system.public_api import get_module
|
||||
|
||||
register_command = get_module("standard.command_helper", "register_command")
|
||||
|
||||
register_command("my_command", "Описание моей команды", role="ADMIN")
|
||||
```
|
||||
28
src/ocab_modules/ocab_modules/standard/config/README.md
Normal file
28
src/ocab_modules/ocab_modules/standard/config/README.md
Normal file
@@ -0,0 +1,28 @@
|
||||
# Модуль Config
|
||||
|
||||
Модуль `config` управляет конфигурацией бота.
|
||||
|
||||
## Функциональность
|
||||
|
||||
- Загрузка конфигурации из файла `config.yaml`.
|
||||
- Сохранение конфигурации в файл.
|
||||
- Регистрация параметров конфигурации.
|
||||
- Получение значений параметров.
|
||||
|
||||
## Использование
|
||||
|
||||
1. Импортируйте объект `config`.
|
||||
2. Вызовите метод `register`, чтобы зарегистрировать параметр конфигурации.
|
||||
3. Вызовите метод `get`, чтобы получить значение параметра.
|
||||
|
||||
## Пример
|
||||
|
||||
```python
|
||||
from ocab_core.modules_system.public_api import get_module
|
||||
|
||||
config = get_module("standard.config", "config")
|
||||
|
||||
config.register("my_parameter", "string", default_value="default")
|
||||
|
||||
value = config.get("my_parameter")
|
||||
```
|
||||
@@ -36,8 +36,19 @@ class ConfigManager:
|
||||
def save(self, file_path: str = ""):
|
||||
if not file_path:
|
||||
file_path = self.config_path
|
||||
|
||||
def nested_dict(flat_dict):
|
||||
result = {}
|
||||
for key, value in flat_dict.items():
|
||||
keys = key.split("::")
|
||||
d = result
|
||||
for k in keys[:-1]:
|
||||
d = d.setdefault(k, {})
|
||||
d[keys[-1]] = value
|
||||
return result
|
||||
|
||||
with open(file_path, "w", encoding="utf-8") as file:
|
||||
yaml.dump(self._config, file, allow_unicode=True)
|
||||
yaml.dump(nested_dict(self._config), file, allow_unicode=True)
|
||||
|
||||
def _check_rights(self, key, module_id, access_type="get"):
|
||||
return
|
||||
@@ -58,6 +69,16 @@ class ConfigManager:
|
||||
module_id = caller_globals.get("__ocab_module_id__")
|
||||
return module_id
|
||||
|
||||
def mass_set(self, updates: Dict[str, Any]):
|
||||
module_id = self._get_module_id()
|
||||
for key, value in updates.items():
|
||||
self._check_rights(key, module_id, "set")
|
||||
if key in self._metadata:
|
||||
# TODO: add checks to validate the type and value based on metadata
|
||||
self._config[key] = value
|
||||
else:
|
||||
raise KeyError(f"Key {key} is not registered.")
|
||||
|
||||
def register(
|
||||
self,
|
||||
key: str,
|
||||
|
||||
@@ -15,6 +15,7 @@ def register_settings_page():
|
||||
path="/settings",
|
||||
blueprint=get_miniapp_blueprint(config, prefix),
|
||||
prefix=prefix,
|
||||
role="ADMIN",
|
||||
)
|
||||
pass
|
||||
|
||||
|
||||
@@ -1,13 +1,22 @@
|
||||
import asyncio
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from .config_manager import ConfigManager
|
||||
|
||||
try:
|
||||
import dash_bootstrap_components as dbc
|
||||
import flask
|
||||
from dash_extensions.enrich import ALL, Input, Output, State, dcc, html
|
||||
|
||||
DASH_AVAILABLE = True
|
||||
except ImportError:
|
||||
DASH_AVAILABLE = False
|
||||
|
||||
from ocab_core.modules_system.public_api import get_module
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ocab_modules.standard.roles import Roles as IRoles
|
||||
|
||||
|
||||
def create_control(key: str, config: ConfigManager):
|
||||
value = config.get(key)
|
||||
@@ -126,8 +135,11 @@ def create_settings_components(tree, level=0):
|
||||
|
||||
|
||||
def get_miniapp_blueprint(config: ConfigManager, prefix: str):
|
||||
Roles: "type[IRoles]" = get_module("standard.roles", "Roles")
|
||||
|
||||
roles = Roles()
|
||||
|
||||
import datetime
|
||||
import locale
|
||||
|
||||
from dash_extensions.enrich import DashBlueprint
|
||||
|
||||
@@ -172,6 +184,28 @@ def get_miniapp_blueprint(config: ConfigManager, prefix: str):
|
||||
)
|
||||
def save_settings(n_clicks, values, keys):
|
||||
if n_clicks > 0:
|
||||
user = getattr(flask.g, "user", None)
|
||||
|
||||
if user is None:
|
||||
return (
|
||||
dbc.Alert(
|
||||
"Вы не авторизованы!",
|
||||
color="danger",
|
||||
duration=10000,
|
||||
),
|
||||
"-",
|
||||
)
|
||||
|
||||
if not asyncio.run(roles.check_admin_permission(user["id"])):
|
||||
return (
|
||||
dbc.Alert(
|
||||
"Вы не администратор!",
|
||||
color="danger",
|
||||
duration=10000,
|
||||
),
|
||||
"-",
|
||||
)
|
||||
|
||||
# TODO: добавить валидацию значений
|
||||
|
||||
updated_settings = {}
|
||||
@@ -179,9 +213,18 @@ def get_miniapp_blueprint(config: ConfigManager, prefix: str):
|
||||
key: str = id_dict["key"]
|
||||
if prefix:
|
||||
key = key.removeprefix(f"{prefix}-")
|
||||
|
||||
meta = config.get_meta(key)
|
||||
|
||||
if meta["type"] == "password":
|
||||
if value: # Only update if a new value is provided
|
||||
updated_settings[key] = value
|
||||
else:
|
||||
updated_settings[key] = value
|
||||
|
||||
locale.setlocale(locale.LC_TIME, "ru_RU.UTF-8")
|
||||
config.mass_set(updated_settings)
|
||||
config.save()
|
||||
|
||||
now = datetime.datetime.now()
|
||||
date_str = now.strftime("%H:%M:%S")
|
||||
|
||||
|
||||
29
src/ocab_modules/ocab_modules/standard/filters/README.md
Normal file
29
src/ocab_modules/ocab_modules/standard/filters/README.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# Модуль Filters
|
||||
|
||||
Модуль `filters` предоставляет фильтры для aiogram, которые используются для ограничения доступа к командам
|
||||
и обработчикам событий.
|
||||
|
||||
## Фильтры
|
||||
|
||||
- `ChatModerOrAdminFilter` - пропускает сообщения только от модераторов и администраторов чата.
|
||||
- `ChatNotInApproveFilter` - пропускает сообщения только из чатов, не входящих в список разрешенных.
|
||||
|
||||
## Использование
|
||||
|
||||
Фильтры можно использовать в декораторах `@router.message` и `@router.callback_query`.
|
||||
|
||||
## Пример
|
||||
|
||||
```python
|
||||
from aiogram import Router
|
||||
from ocab_core.modules_system.public_api import get_module
|
||||
|
||||
ChatModerOrAdminFilter = get_module("standard.filters", "ChatModerOrAdminFilter")
|
||||
|
||||
router = Router()
|
||||
|
||||
@router.message(ChatModerOrAdminFilter())
|
||||
async def admin_command(message: Message):
|
||||
# Обработка команды, доступной только администраторам и модераторам.
|
||||
pass
|
||||
```
|
||||
@@ -0,0 +1,13 @@
|
||||
# Модуль FSM Database Storage
|
||||
|
||||
Модуль `fsm_database_storage` реализует хранение состояний FSM (Finite State Machine) в базе данных.
|
||||
|
||||
## Функциональность
|
||||
|
||||
- Сохранение состояния FSM в базу данных.
|
||||
- Получение состояния FSM из базы данных.
|
||||
- Обновление данных состояния FSM.
|
||||
|
||||
## Использование
|
||||
|
||||
Модуль автоматически регистрирует хранилище состояний FSM при инициализации.
|
||||
15
src/ocab_modules/ocab_modules/standard/info/README.md
Normal file
15
src/ocab_modules/ocab_modules/standard/info/README.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# Модуль Info
|
||||
|
||||
Модуль `info` предоставляет информацию о пользователях и чатах.
|
||||
|
||||
## Команды
|
||||
|
||||
- `/info` - получить информацию о пользователе.
|
||||
- `/chatinfo` - получить информацию о чате.
|
||||
|
||||
## Использование
|
||||
|
||||
Чтобы получить информацию о пользователе, отправьте команду `/info`,
|
||||
ответив на сообщение пользователя или указав его тег.
|
||||
|
||||
Чтобы получить информацию о чате, отправьте команду `/chatinfo`.
|
||||
@@ -0,0 +1,14 @@
|
||||
# Модуль Message Processing
|
||||
|
||||
Модуль `message_processing` обрабатывает все входящие сообщения.
|
||||
|
||||
## Функциональность
|
||||
|
||||
- Проверка чата и пользователя на наличие в базе данных.
|
||||
- Обновление информации о чате и пользователе.
|
||||
- Добавление статистики сообщений.
|
||||
- Передача сообщения модулю `yandexgpt`, если оно соответствует условиям.
|
||||
|
||||
## Использование
|
||||
|
||||
Модуль автоматически обрабатывает все входящие сообщения.
|
||||
23
src/ocab_modules/ocab_modules/standard/miniapp/README.md
Normal file
23
src/ocab_modules/ocab_modules/standard/miniapp/README.md
Normal file
@@ -0,0 +1,23 @@
|
||||
# Модуль Miniapp
|
||||
|
||||
Модуль `miniapp` реализует веб-интерфейс для бота, доступный через Telegram Mini Apps.
|
||||
|
||||
## Функциональность
|
||||
|
||||
- Регистрация страниц веб-интерфейса.
|
||||
- Авторизация пользователей через Telegram.
|
||||
|
||||
## Использование
|
||||
|
||||
1. Импортируйте функцию `register_page`.
|
||||
2. Вызовите функцию `register_page`, передав ей название страницы, ее путь, blueprint Dash и префикс.
|
||||
|
||||
## Пример
|
||||
|
||||
```python
|
||||
from ocab_core.modules_system.public_api import get_module
|
||||
|
||||
register_page = get_module("standard.miniapp", "register_page")
|
||||
|
||||
register_page("Моя страница", "/my_page", my_blueprint, prefix="my_page")
|
||||
```
|
||||
@@ -1,13 +1,104 @@
|
||||
import flask
|
||||
from aiogram.utils.web_app import safe_parse_webapp_init_data
|
||||
from dash import Dash
|
||||
from dash_extensions.enrich import Input
|
||||
from dash_extensions.enrich import Input, Output
|
||||
from flask import request
|
||||
|
||||
# TODO: добавить прокидывание BASE_PATH, т.к. это параметр из настроек
|
||||
|
||||
WEBAPP_LOADER_TEMPLATE = """
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>OCAB</title>
|
||||
<script src="https://telegram.org/js/telegram-web-app.js"></script>
|
||||
<script>
|
||||
window.addEventListener('message', function(event) {
|
||||
if (event.origin !== window.location.origin) return;
|
||||
if (event.data.type === 'iframe-url-changed') {
|
||||
history.pushState(
|
||||
null,
|
||||
'',
|
||||
window.BASE_PATH + event.data.pathname.substring(
|
||||
window.INTERNAL_PATH.length
|
||||
)
|
||||
);
|
||||
}
|
||||
});
|
||||
window.addEventListener('popstate', function(event) {
|
||||
var iframe = document.getElementById('app-frame');
|
||||
var iframeWindow = iframe.contentWindow;
|
||||
iframeWindow.history.back();
|
||||
});
|
||||
</script>
|
||||
<style>
|
||||
#app-frame {
|
||||
display:none;
|
||||
width:100%;
|
||||
height:100vh;
|
||||
border:none;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="loading">Loading...</div>
|
||||
<iframe id="app-frame"></iframe>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const tg = window.Telegram.WebApp;
|
||||
document.cookie = `tg_init_data=${JSON.stringify(tg.initData)}; path=/`;
|
||||
|
||||
// if (!tg.initData) return;
|
||||
|
||||
const iframe = document.getElementById('app-frame');
|
||||
|
||||
// Константы для путей
|
||||
const BASE_PATH = '/webapp';
|
||||
const INTERNAL_PATH = '/webapp/_internal';
|
||||
|
||||
window.BASE_PATH = BASE_PATH;
|
||||
window.INTERNAL_PATH = INTERNAL_PATH
|
||||
|
||||
// Текущий путь страницы
|
||||
const currentPath = window.location.pathname;
|
||||
|
||||
// Формируем новый путь для iframe
|
||||
let iframeSrc = INTERNAL_PATH;
|
||||
|
||||
// Если текущий путь начинается с BASE_PATH, убираем BASE_PATH из текущего пути
|
||||
if (currentPath.startsWith(BASE_PATH)
|
||||
&& currentPath.length > BASE_PATH.length) {
|
||||
iframeSrc += currentPath.substring(BASE_PATH.length);
|
||||
} else if (currentPath !== '/') {
|
||||
iframeSrc += currentPath;
|
||||
}
|
||||
|
||||
iframe.src = iframeSrc;
|
||||
|
||||
iframe.onload = function() {
|
||||
document.getElementById('loading').style.display = 'none';
|
||||
iframe.style.display = 'block';
|
||||
};
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
|
||||
|
||||
def get_auth_server(bot_token: str):
|
||||
server = flask.Flask(__name__)
|
||||
|
||||
@server.route("/<path:rest>")
|
||||
@server.route("/")
|
||||
def webapp_loader(rest=None):
|
||||
return flask.Response(WEBAPP_LOADER_TEMPLATE, mimetype="text/html")
|
||||
|
||||
@server.before_request
|
||||
def add_auth_data():
|
||||
init_data = request.cookies.get("tg_init_data")
|
||||
@@ -21,13 +112,35 @@ def get_auth_server(bot_token: str):
|
||||
return server
|
||||
|
||||
|
||||
def setup_auth_clientcallback(app: Dash):
|
||||
def setup_auth_clientcallbacks(app: Dash):
|
||||
app.clientside_callback(
|
||||
"""
|
||||
function(n_inervals) {
|
||||
const tg = window.Telegram.WebApp;
|
||||
document.cookie = `tg_init_data=${JSON.stringify(tg.initData)}; path=/`;
|
||||
function(n_intervals) {
|
||||
if (window.webAppData) {
|
||||
return window.webAppData;
|
||||
}
|
||||
|
||||
function receiveMessage(event) {
|
||||
if (event.data.type === 'webAppData') {
|
||||
window.webAppData = event.data.webApp;
|
||||
window.removeEventListener('message', receiveMessage);
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener('message', receiveMessage, false);
|
||||
|
||||
return window.dash_clientside.no_update;
|
||||
}
|
||||
""",
|
||||
Input("init-telegram-interval", "n_intervals"),
|
||||
Output("hidden-div", "children"),
|
||||
Input("interval-component", "n_intervals"),
|
||||
)
|
||||
|
||||
app.clientside_callback(
|
||||
"""
|
||||
function(pathname) {
|
||||
window.parent.postMessage({ type: 'iframe-url-changed', pathname }, '*');
|
||||
}
|
||||
""",
|
||||
Input("url", "pathname"),
|
||||
)
|
||||
|
||||
@@ -1,26 +1,30 @@
|
||||
import asyncio
|
||||
from collections import OrderedDict
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import dash
|
||||
import dash_bootstrap_components as dbc
|
||||
import flask
|
||||
from dash_extensions.enrich import DashBlueprint, DashProxy, Input, Output, dcc, html
|
||||
from dash_extensions.pages import setup_page_components
|
||||
|
||||
from ocab_core.modules_system.public_api import get_module
|
||||
from ocab_core.modules_system.public_api import get_module, log
|
||||
|
||||
from .dash_telegram_auth import get_auth_server, setup_auth_clientcallback
|
||||
from .dash_telegram_auth import get_auth_server, setup_auth_clientcallbacks
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ocab_modules.standard.config import IConfig
|
||||
from ocab_modules.standard.roles import Roles as IRoles
|
||||
|
||||
pages = OrderedDict()
|
||||
|
||||
|
||||
def register_page(name, path, blueprint, prefix=""):
|
||||
def register_page(name, path, blueprint, prefix="", role="USER"):
|
||||
pages[path] = {
|
||||
"name": name,
|
||||
"blueprint": blueprint,
|
||||
"prefix": prefix,
|
||||
"role": role,
|
||||
}
|
||||
|
||||
|
||||
@@ -33,9 +37,14 @@ def register_home_page():
|
||||
register_home_page()
|
||||
|
||||
config: "IConfig" = get_module("standard.config", "config")
|
||||
Roles: "type[IRoles]" = get_module("standard.roles", "Roles")
|
||||
|
||||
|
||||
def create_dash_app(requests_pathname_prefix: str = None) -> dash.Dash:
|
||||
log(requests_pathname_prefix)
|
||||
|
||||
real_prefix = f"{requests_pathname_prefix}_internal/"
|
||||
|
||||
server = get_auth_server(config.get("core::token"))
|
||||
|
||||
app = DashProxy(
|
||||
@@ -47,10 +56,13 @@ def create_dash_app(requests_pathname_prefix: str = None) -> dash.Dash:
|
||||
dbc.icons.BOOTSTRAP,
|
||||
],
|
||||
external_scripts=[
|
||||
#
|
||||
"https://telegram.org/js/telegram-web-app.js"
|
||||
], # Add Telegram Mini Apps script to <head>
|
||||
],
|
||||
server=server,
|
||||
requests_pathname_prefix=requests_pathname_prefix,
|
||||
requests_pathname_prefix=real_prefix,
|
||||
routes_pathname_prefix="/_internal/",
|
||||
# requests_pathname_prefix=requests_pathname_prefix,
|
||||
meta_tags=[
|
||||
{"name": "viewport", "content": "width=device-width, initial-scale=1"},
|
||||
],
|
||||
@@ -63,30 +75,8 @@ def create_dash_app(requests_pathname_prefix: str = None) -> dash.Dash:
|
||||
|
||||
# Register pages
|
||||
for path, page in pages.items():
|
||||
# dash.register_page(page["name"], path=path, layout=page["layout"])
|
||||
page["blueprint"].register(app, path, prefix=page["prefix"])
|
||||
|
||||
# Create sidebar
|
||||
sidebar = dbc.Offcanvas(
|
||||
id="offcanvas",
|
||||
title="Меню",
|
||||
is_open=False,
|
||||
children=[
|
||||
dbc.Nav(
|
||||
[
|
||||
dbc.NavLink(
|
||||
page["name"],
|
||||
href=f"{requests_pathname_prefix}{path.lstrip('/')}",
|
||||
id={"type": "nav-link", "index": path},
|
||||
)
|
||||
for path, page in pages.items()
|
||||
],
|
||||
vertical=True,
|
||||
pills=True,
|
||||
),
|
||||
],
|
||||
)
|
||||
|
||||
# Create navbar
|
||||
navbar = dbc.Navbar(
|
||||
dbc.Container(
|
||||
@@ -104,8 +94,47 @@ def create_dash_app(requests_pathname_prefix: str = None) -> dash.Dash:
|
||||
dark=True,
|
||||
)
|
||||
|
||||
# Define app layout
|
||||
app.layout = html.Div(
|
||||
roles = Roles()
|
||||
|
||||
def create_layout():
|
||||
user = getattr(flask.g, "user", None)
|
||||
|
||||
if not user:
|
||||
return html.Div()
|
||||
|
||||
user_id = user["id"]
|
||||
user_permission = asyncio.run(roles.get_user_permission(user_id)) or "USER"
|
||||
|
||||
available_pages = {
|
||||
path: page
|
||||
for path, page in pages.items()
|
||||
if (isinstance(page["role"], list) and user_permission in page["role"])
|
||||
or page["role"] == user_permission
|
||||
or page["role"] == "USER"
|
||||
}
|
||||
|
||||
# Create sidebar
|
||||
sidebar = dbc.Offcanvas(
|
||||
id="offcanvas",
|
||||
title="Меню",
|
||||
is_open=False,
|
||||
children=[
|
||||
dbc.Nav(
|
||||
[
|
||||
dbc.NavLink(
|
||||
page["name"],
|
||||
href=f"{real_prefix}/{path.lstrip('/')}",
|
||||
id={"type": "nav-link", "index": path},
|
||||
)
|
||||
for path, page in available_pages.items()
|
||||
],
|
||||
vertical=True,
|
||||
pills=True,
|
||||
),
|
||||
],
|
||||
)
|
||||
|
||||
layout = html.Div(
|
||||
[
|
||||
dcc.Location(id="url", refresh=False),
|
||||
dcc.Interval(
|
||||
@@ -121,7 +150,11 @@ def create_dash_app(requests_pathname_prefix: str = None) -> dash.Dash:
|
||||
]
|
||||
)
|
||||
|
||||
setup_auth_clientcallback(app)
|
||||
return layout
|
||||
|
||||
app.layout = create_layout
|
||||
|
||||
setup_auth_clientcallbacks(app)
|
||||
|
||||
# Открытие на кнопку меню
|
||||
app.clientside_callback(
|
||||
|
||||
36
src/ocab_modules/ocab_modules/standard/roles/README.md
Normal file
36
src/ocab_modules/ocab_modules/standard/roles/README.md
Normal file
@@ -0,0 +1,36 @@
|
||||
# Модуль Roles
|
||||
|
||||
Модуль `roles` управляет ролями пользователей.
|
||||
|
||||
## Роли
|
||||
|
||||
- `USER` - обычный пользователь.
|
||||
- `MODERATOR` - модератор.
|
||||
- `ADMIN` - администратор.
|
||||
- `BOT` - бот.
|
||||
|
||||
## Функциональность
|
||||
|
||||
- Проверка роли пользователя.
|
||||
- Получение имени роли по ID.
|
||||
- Получение ID роли по имени.
|
||||
|
||||
## Использование
|
||||
|
||||
1. Импортируйте класс `Roles`.
|
||||
2. Создайте экземпляр класса.
|
||||
3. Вызовите методы класса для проверки роли пользователя или получения имени роли.
|
||||
|
||||
## Пример
|
||||
|
||||
```python
|
||||
from ocab_core.modules_system.public_api import get_module
|
||||
|
||||
Roles = get_module("standard.roles", "Roles")
|
||||
|
||||
roles = Roles()
|
||||
|
||||
is_admin = await roles.check_admin_permission(user_id)
|
||||
|
||||
role_name = await roles.get_role_name(role_id)
|
||||
```
|
||||
1462
src/ocab_modules/poetry.lock
generated
1462
src/ocab_modules/poetry.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -17,6 +17,8 @@ dash = "^2.17.1"
|
||||
dash-extensions = "^1.0.18"
|
||||
dash-bootstrap-components = "^1.6.0"
|
||||
|
||||
[tool.poetry-monorepo.deps]
|
||||
enabled = true
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core"]
|
||||
|
||||
Reference in New Issue
Block a user