Skip to main content

mnemosynecore

mnemosynecore — Python-библиотека для аналитиков и data-инженеров.

Главная идея: писать меньше служебного кода в DAG/ноутбуках и быстрее решать рабочие задачи:

  • достать секреты и подключения,
  • выполнить SQL в Vertica,
  • отправить отчёт в Mattermost,
  • сделать скриншот Superset,
  • быстро обратиться к LLM через один вызов,
  • скачать файл из SharePoint,
  • добавить надёжные retry.

Зачем это аналитикам

Эта библиотека убирает рутину:

  • не нужно каждый раз вручную писать код авторизации,
  • одинаковый подход в проде и локально,
  • проще проверять логику до выкладки в Airflow,
  • меньше копипаста между задачами команды.

Установка

pip install mnemosynecore

Опциональные зависимости:

# Airflow helpers
pip install "mnemosynecore[airflow]"

# Superset API
pip install "mnemosynecore[superset]"

# SharePoint NTLM
pip install "mnemosynecore[sharepoint]"

# ClickHouse через un_conn
pip install "mnemosynecore[clickhouse]"

# Визуализация (PNG графики)
pip install "mnemosynecore[viz]"

# Всё вместе
pip install "mnemosynecore[airflow,superset,sharepoint,clickhouse,viz]"

Быстрый старт (2 минуты)

import mnemosynecore as mn

# 1) взять секрет
cfg = mn.get_secret("VERTICA_PROD")
print(cfg["host"])

# 2) выполнить SQL
df = mn.vertica_select(
    conn_id="VERTICA_PROD",
    sql="SELECT CURRENT_DATE AS dt",
)
print(df)

Готовые скрипты с рабочими примерами лежат в папке examples/:

  • examples/01_secrets_and_test_mode.py
  • examples/02_vertica_examples.py
  • examples/03_mattermost_examples.py
  • examples/04_superset_examples.py
  • examples/05_sharepoint_examples.py
  • examples/06_superset_links_and_threads.py
  • examples/07_llm_examples.py
  • examples/08_mattermost_emoji_letters.py
  • examples/09_reporting_examples.py
  • examples/10_viz_examples.py

Обычные функции и _test-функции

Почти для всех интеграционных функций есть пара:

  • обычная: работает с ENV/Vault/Airflow,
  • _test: для локального запуска с JSON-кредами.

Пример пары:

  • vertica_select(...)
  • vertica_select_test(..., dir_path=... | creds_path=...)

Как передавать креды локально

Есть 2 способа:

  1. dir_path — путь к папке, где лежит <CONN_ID>.json
  2. creds_path — прямой путь к файлу JSON

Пример:

# Файл: ./local_secrets/VERTICA_DEV.json
df = mn.vertica_select_test(
    conn_id="VERTICA_DEV",
    sql="SELECT 1",
    dir_path="./local_secrets",
)

# Файл: /Users/me/secrets/vertica_dev.json
df = mn.vertica_select_test(
    conn_id="VERTICA_DEV",
    sql="SELECT 1",
    creds_path="/Users/me/secrets/vertica_dev.json",
)

Формат JSON-кредов

Универсальный формат:

{
  "host": "example.host",
  "login": "user",
  "password": "secret",
  "port": 443,
  "schema": "https",
  "extra": "{\"basepath\":\"/api/v4\"}"
}

Mattermost

{
  "host": "mattermost.company.ru",
  "password": "BOT_TOKEN",
  "schema": "https",
  "port": 443,
  "extra": "{\"basepath\":\"/api/v4\"}"
}

Можно использовать не только бот-токен, но и личный user-token:

  • передайте его в password (JSON/секрет),
  • сообщение будет отправлено от имени владельца этого токена.

Superset

{
  "host": "https://ss.company.ru",
  "login": "svc_user",
  "password": "svc_password",
  "extra": "{\"auth_provider\":\"ldap\"}"
}

LLM (OpenAI-compatible gateway/API)

{
  "host": "http://llm-gateway.prod.a.o3.ru/api",
  "password": "LLM_TOKEN",
  "model": "DeepSeek-V3-0324-AWQ[CM]",
  "extra": "{\"endpoint\":\"/chat/completions\"}"
}

Для Vertica/коннектов можно указывать и login, и user:

  • если есть user, библиотека использует его,
  • если user нет, берется login.

SharePoint

{
  "host": "https://sharepoint.company.ru",
  "login": "svc_sharepoint",
  "password": "svc_password",
  "schema": "O3"
}

Примеры: секреты и подключения

import mnemosynecore as mn

# Прод: ENV/Vault/Airflow
secret = mn.get_secret("MM_BOT")

# Локально: из JSON
secret_test = mn.get_secret_test("MM_BOT", dir_path="./secrets")
secret_test2 = mn.get_secret_test("MM_BOT", creds_path="./secrets/mm_bot.json")

# Универсально: сначала локально, если не нашли — прод
cfg = mn.resolve_secret("MM_BOT", dir_path="./secrets")

# Проверка обязательных полей
mn.require_secret_fields("MM_BOT", ["host", "password"])

Примеры: Vertica

import pandas as pd
import mnemosynecore as mn

# 1) SELECT
sales_df = mn.vertica_select(
    conn_id="VERTICA_PROD",
    sql="""
    SELECT dt, revenue
    FROM mart.daily_sales
    WHERE dt >= CURRENT_DATE - INTERVAL '7 day'
    """,
)

# 2) Scalar
row_count = mn.vertica_select_scalar(
    conn_id="VERTICA_PROD",
    sql="SELECT COUNT(*) FROM mart.daily_sales",
)

# 3) Выполнить SQL из файла
mn.vertica_sql_file(
    file_path="./sql/rebuild_mart.sql",
    conn_id="VERTICA_PROD",
)

# 4) Upsert из DataFrame
new_rows = pd.DataFrame([
    {"id": 1, "dt": "2026-03-01", "revenue": 10.0},
    {"id": 2, "dt": "2026-03-01", "revenue": 20.0},
])
mn.vertica_upsert(
    df=new_rows,
    table_name="mart.daily_sales",
    unique_keys=["id", "dt"],
    conn_id="VERTICA_PROD",
)

# 5) Локальный тест через JSON
test_df = mn.vertica_select_test(
    conn_id="VERTICA_DEV",
    sql="SELECT 1 AS x",
    dir_path="./secrets",
)

Примеры: Mattermost

import pandas as pd
import mnemosynecore as mn

# Текстовое сообщение
mn.send_message(
    channel_id="channel_id_here",
    bot_id="MM_BOT",
    text="Ежедневный отчёт готов",
)

# Короткий алиас (то же самое)
mn.send_text(
    channel_id="channel_id_here",
    bot_id="MM_BOT",
    text="Ежедневный отчёт готов",
)

# Файл
mn.send_file(
    channel_id="channel_id_here",
    bot_id="MM_BOT",
    file_path="./reports/daily_sales.xlsx",
    text="Отчёт во вложении",
)

# DataFrame как CSV
df = pd.DataFrame([{"country": "RU", "value": 100}])
mn.send_dataframe_as_csv(
    channel_id="channel_id_here",
    bot_id="MM_BOT",
    df=df,
    file_name="daily_metrics.csv",
)

# Локально (_test) с creds_path
mn.send_message_test(
    channel_id="channel_id_here",
    bot_id="MM_BOT",
    text="Проверка локальной отправки",
    creds_path="./secrets/mm_bot.json",
)

# Ответ в тред обычным текстом
mn.send_thread_message(
    channel_id="channel_id_here",
    bot_id="MM_BOT",
    root_id="post_id_основного_сообщения",
    text="Дополнительный комментарий в тред",
)

# Короткий алиас для ответа в тред
mn.reply_text(
    channel_id="channel_id_here",
    bot_id="MM_BOT",
    root_id="post_id_основного_сообщения",
    text="Ещё один комментарий в тред",
)

# Можно и файл/таблицу отправить прямо в тред через root_id
mn.send_dataframe_as_csv(
    channel_id="channel_id_here",
    bot_id="MM_BOT",
    root_id="post_id_основного_сообщения",
    df=df,
    file_name="details.csv",
)

# Текст "буквенными" emoji:
# "tipa takogo" -> :t_letter: :i_letter: :p_letter: ...
mn.send_message_as_letter_emojis(
    channel_id="channel_id_here",
    bot_id="MM_BOT_OR_PERSONAL_TOKEN_CONN",
    text="tipa takogo",
)

# Поставить реакции-буквы к посту (слово из реакций)
mn.add_letter_emoji_reactions(
    post_id="post_id_here",
    bot_id="MM_BOT_OR_PERSONAL_TOKEN_CONN",
    text="ok",
)

# Важно: одинаковую реакцию один пользователь обычно не может поставить дважды.
# Поэтому для слов с повторяющимися буквами повторы по умолчанию пропускаются.

Примеры: Superset

import mnemosynecore as mn

# Скриншот дашборда (bytes)
png = mn.superset_dashboard_thumbnail(
    superset_conn="SUPERSET_CONN",
    dashboard_name="Финансы - ежедневный обзор",
)

# Отправить скриншот дашборда в Mattermost
mn.send_superset_dashboard_screenshot(
    channel_id="channel_id_here",
    bot_id="MM_BOT",
    superset_conn="SUPERSET_CONN",
    dashboard_name="Финансы - ежедневный обзор",
    text="Скриншот утреннего дашборда",
)

# Локально (_test) с JSON кредами
mn.superset_chart_thumbnail_test(
    superset_conn="SUPERSET_CONN",
    chart_id=31729,
    creds_path="./secrets/superset_conn.json",
)

# Ссылка на дашборд (markdown)
dash_link = mn.superset_dashboard_link(
    superset_conn="SUPERSET_CONN",
    dashboard_id=145,
    dashboard_name="Daily KPI",
)

# Отправка только ссылки в канал
mn.send_superset_dashboard_link(
    channel_id="channel_id_here",
    bot_id="MM_BOT",
    superset_conn="SUPERSET_CONN",
    dashboard_id=145,
    dashboard_name="Daily KPI",
    text="Отчёт на сегодня",
)

# Ссылки на дашборды в тред + обычные текстовые сообщения в этом же треде
mn.send_superset_dashboard_links_to_thread(
    channel_id="channel_id_here",
    bot_id="MM_BOT",
    superset_conn="SUPERSET_CONN",
    dashboards=[
        {"dashboard_name": "Main", "id": 145},
        {"dashboard_name": "Finance", "id": 146},
    ],
    header_text="Ежедневная подборка дашбордов",
    thread_messages=[
        "Если график выглядит странно, пишите в этот тред.",
        "Детали по фильтрам приложу чуть позже.",
    ],
)

# Сохранить скриншот в конкретный файл
mn.superset_dashboard_screenshot_to_file(
    superset_conn="SUPERSET_CONN",
    dashboard_id=145,
    output_path="./tmp/daily_kpi_dashboard.png",
)

# Новый быстрый сценарий:
# взяли permalink из UI Superset (с фильтрами) и отправили скрин + ссылку
mn.send_superset_dashboard_permalink_screenshot(
    channel_id="channel_id_here",
    bot_id="MM_BOT",
    superset_conn="SUPERSET_CONN",
    dashboard_name="Daily KPI (filtered)",
    dashboard_url="https://ss.company.ru/superset/dashboard/p/AbCdEf123/?native_filters_key=...",
    text="Борд с применёнными фильтрами из UI",
)

Примеры: LLM

import mnemosynecore as mn

# 1) Самый быстрый вариант: token + model + prompt параметрами
answer = mn.llm_chat(
    prompt="Сделай 3 пункта summary по таблице заказов",
    model="gpt-4o-mini",
    token="your_token_here",
    base_url="https://api.openai.com/v1",
)
print(answer)

# 2) Токен из файла (txt/json)
answer2 = mn.llm_chat(
    prompt="Объясни разницу между DAU и MAU в 2 предложениях",
    model="DeepSeek-V3-0324-AWQ[CM]",
    token_path="./secrets/llm_token.txt",
    base_url="http://llm-gateway.prod.a.o3.ru/api",
)

# 3) Через Vault/ENV/Airflow по conn_id (host/token/model в секрете)
answer3 = mn.llm_chat(
    prompt="Сгенерируй чек-лист проверки витрины перед релизом",
    llm_conn="LLM_GATEWAY",
)

# 4) Локально (_test): указать прямой путь к файлу с кредами
answer4 = mn.llm_chat_test(
    prompt="Верни JSON: {\"ok\": true}",
    llm_conn="LLM_GATEWAY",
    creds_path="./secrets/LLM_GATEWAY.json",
    parse_json=True,
)
print(answer4)  # {'ok': True}

Примеры: Reporting utilities

import pandas as pd
import mnemosynecore as mn

# 1) SQL -> preview + CSV в Mattermost за один вызов
mn.send_query_report(
    channel_id="channel_id_here",
    bot_id="MM_BOT",
    conn_id="VERTICA_PROD",
    sql="SELECT * FROM mart.kpi_daily WHERE dt = CURRENT_DATE - 1",
    header_text="KPI за вчера",
)

# 2) KPI current vs previous
mn.send_kpi_report(
    channel_id="channel_id_here",
    bot_id="MM_BOT",
    conn_id="VERTICA_PROD",
    current_sql="SELECT metric, value FROM mart.kpi_current",
    previous_sql="SELECT metric, value FROM mart.kpi_previous",
)

# 3) Data quality report
df = pd.DataFrame([
    {"id": 1, "value": 10, "dt": "2026-03-01"},
    {"id": 1, "value": 10, "dt": "2026-03-01"},
    {"id": 2, "value": None, "dt": "2026-03-02"},
])
dq = mn.data_quality_report(df=df, freshness_col="dt")
print(mn.format_data_quality_report(dq))

mn.send_data_quality_report(
    channel_id="channel_id_here",
    bot_id="MM_BOT",
    df=df,
    freshness_col="dt",
)

# 4) SharePoint файл -> Vertica
mn.sharepoint_to_vertica(
    sharepoint_conn="SP_CONN",
    file_url="/sites/analytics/input/kpi.csv",
    table_name="stg.kpi_input",
    vertica_conn_id="VERTICA_PROD",
    mode="upsert",
    unique_keys=["id"],
)

Примеры: Визуализация

import pandas as pd
import mnemosynecore as mn

df = pd.DataFrame([
    {"dt": "2026-03-01", "revenue": 100, "orders": 10},
    {"dt": "2026-03-02", "revenue": 120, "orders": 12},
    {"dt": "2026-03-03", "revenue": 90, "orders": 9},
])

line_png = mn.plot_line_png(df=df, x="dt", y=["revenue", "orders"], title="Revenue and Orders")
bar_png = mn.plot_bar_png(df=df, x="dt", y="revenue", title="Revenue by day")
heat_png = mn.plot_heatmap_png(df=df[["revenue", "orders"]], title="Heatmap")

mn.send_plot(
    channel_id="channel_id_here",
    bot_id="MM_BOT",
    png_bytes=line_png,
    file_name="line.png",
    text="Линейный график",
)

Примеры: SharePoint

import mnemosynecore as mn

# Скачать файл в память
content = mn.sharepoint_download_file(
    sharepoint_conn="SP_CONN",
    file_url="/sites/analytics/reports/plan.csv",
)

# Прочитать CSV сразу в DataFrame
df = mn.sharepoint_read_csv(
    sharepoint_conn="SP_CONN",
    file_url="/sites/analytics/reports/plan.csv",
)

# Сохранить файл локально
mn.sharepoint_download_to_file(
    sharepoint_conn="SP_CONN",
    file_url="/sites/analytics/reports/plan.csv",
    output_path="./tmp/plan.csv",
)

# Локально (_test)
df_local = mn.sharepoint_read_csv_test(
    sharepoint_conn="SP_CONN",
    file_url="/sites/analytics/reports/plan.csv",
    dir_path="./secrets",
)

Примеры готовых сценариев для аналитика

Сценарий 1: загрузить данные из SharePoint и отправить summary в Mattermost

import mnemosynecore as mn

df = mn.sharepoint_read_csv(
    sharepoint_conn="SP_CONN",
    file_url="/sites/analytics/input/sales.csv",
)

summary = df.groupby("country", as_index=False)["amount"].sum()

mn.send_dataframe_preview(
    channel_id="channel_id_here",
    bot_id="MM_BOT",
    df=summary,
    title="Сумма продаж по странам",
)

Сценарий 2: выполнить SQL и отправить CSV в Mattermost

import mnemosynecore as mn

df = mn.vertica_select(
    conn_id="VERTICA_PROD",
    sql="SELECT * FROM mart.kpi_daily WHERE dt = CURRENT_DATE - 1",
)

mn.send_dataframe_as_csv(
    channel_id="channel_id_here",
    bot_id="MM_BOT",
    df=df,
    file_name="kpi_daily.csv",
    text="KPI за вчера",
)

Сценарий 3: nightly-скриншоты Superset в разные каналы

import mnemosynecore as mn

mn.send_superset_dashboards_to_channels(
    bot_id="MM_BOT",
    superset_conn="SUPERSET_CONN",
    dashboards=[
        {
            "dashboard_name": "Продажи - общий",
            "channel_id": "sales_channel",
            "text": "Утренний срез",
        },
        {
            "dashboard_name": "Логистика - SLA",
            "channel_id": "ops_channel",
            "text": "SLA на утро",
        },
    ],
)

Основные группы API

Секреты

  • get_connection_as_json, get_connection_as_json_test
  • get_secret, get_secret_test
  • resolve_secret, resolve_secret_test
  • has_connection, get_secret_field, require_secret_fields, get_secret_with_defaults

Vertica

  • vertica_conn, vertica_conn_test
  • vertica_sql, vertica_sql_test
  • vertica_select, vertica_select_test
  • vertica_select_scalar, vertica_select_scalar_test
  • vertica_insert_dataframe, vertica_insert_dataframe_test
  • vertica_sql_file, vertica_sql_file_test
  • vertica_sql_dir, vertica_sql_dir_test
  • vertica_dedupe, vertica_dedupe_test
  • vertica_upsert, vertica_upsert_test

Mattermost

  • post_message, post_message_test
  • send_message, send_message_test
  • send_text, send_text_test (короткие алиасы)
  • send_thread_message, send_thread_message_test
  • reply_text, reply_text_test (короткие алиасы)
  • send_thread_messages, send_thread_messages_test
  • send_file, send_file_test
  • send_file_bytes, send_file_bytes_test
  • send_files, send_files_test
  • send_dataframe_as_csv, send_dataframe_as_csv_test
  • send_dataframe_preview, send_dataframe_preview_test
  • text_to_letter_emojis
  • send_message_as_letter_emojis, send_message_as_letter_emojis_test
  • add_letter_emoji_reactions, add_letter_emoji_reactions_test

Superset

  • get_superset_client, get_superset_client_test
  • superset_request, superset_request_test
  • superset_dashboard_url, superset_dashboard_url_test
  • superset_chart_url, superset_chart_url_test
  • superset_dashboard_link, superset_dashboard_link_test
  • superset_chart_link, superset_chart_link_test
  • superset_dashboard_thumbnail, superset_dashboard_thumbnail_test
  • superset_chart_thumbnail, superset_chart_thumbnail_test
  • superset_dashboard_screenshot_to_file, superset_dashboard_screenshot_to_file_test
  • superset_chart_screenshot_to_file, superset_chart_screenshot_to_file_test
  • superset_screenshot_dashboard, superset_screenshot_dashboard_test
  • superset_screenshot_charts, superset_screenshot_charts_test
  • send_superset_dashboard_screenshot, send_superset_dashboard_screenshot_test
  • send_superset_dashboard_permalink_screenshot, send_superset_dashboard_permalink_screenshot_test
  • send_superset_chart_screenshot, send_superset_chart_screenshot_test
  • send_superset_dashboard_link, send_superset_dashboard_link_test
  • send_superset_chart_link, send_superset_chart_link_test
  • send_superset_dashboard_links_to_thread, send_superset_dashboard_links_to_thread_test
  • send_superset_chart_links_to_thread, send_superset_chart_links_to_thread_test
  • send_superset_dashboards_to_channels, send_superset_dashboards_to_channels_test
  • send_superset_charts_to_channels, send_superset_charts_to_channels_test

SharePoint

  • sharepoint_download_file, sharepoint_download_file_test
  • sharepoint_download_to_file, sharepoint_download_to_file_test
  • sharepoint_read_text, sharepoint_read_text_test
  • sharepoint_read_dataframe, sharepoint_read_dataframe_test
  • sharepoint_read_csv, sharepoint_read_csv_test
  • sharepoint_read_excel, sharepoint_read_excel_test
  • sharepoint_read_json, sharepoint_read_json_test
  • sharepoint_read_sql, sharepoint_read_sql_test
  • sharepoint_download_many, sharepoint_download_many_test

Reporting

  • send_query_report, send_query_report_test
  • send_kpi_report, send_kpi_report_test
  • data_quality_report
  • format_data_quality_report
  • send_data_quality_report, send_data_quality_report_test
  • sharepoint_to_vertica, sharepoint_to_vertica_test

LLM

  • llm_chat, llm_chat_test
  • llm_summarize_dataframe, llm_summarize_dataframe_test
  • llm_explain_kpi_delta, llm_explain_kpi_delta_test
  • llm_write_mattermost_update, llm_write_mattermost_update_test
  • llm_classify_texts, llm_classify_texts_test

Визуализация

  • plot_line_png
  • plot_bar_png
  • plot_heatmap_png
  • send_plot, send_plot_test

Retry

  • retry_call, retry

Локальная проверка перед релизом

pytest -q

Релиз и публикация

В проекте есть скрипт release.sh:

  • повышает версию,
  • запускает тесты,
  • собирает пакет,
  • публикует в TestPyPI/PyPI,
  • делает commit/push.

Примеры:

# Только TestPyPI
./release.sh --target testpypi

# TestPyPI + PyPI
./release.sh --target both

# Явно задать версию
./release.sh --version 1.2.0 --target both

Для публикации нужен токен Twine (~/.pypirc или переменные TWINE_*).

Metadata

Release files for mnemosynecore 1.1.8

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for mnemosynecore 1.1.8
File Size Uploaded
mnemosynecore-1.1.8.tar.gz 58.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for mnemosynecore 1.1.8
File Interpreter ABI Platform
mnemosynecore-1.1.8-py3-none-any.whl Python 3 none any Details

Total release size: 101.6 kB

Release files / mnemosynecore-1.1.8.tar.gz

Download URL mnemosynecore-1.1.8.tar.gz
Size 58.6 kB
Tags Source
SHA-256 checksum
How to use checksums
703a24a210423b4baf1046c088907b56d084004ba79513db9188afb7e93be9e1
BLAKE2b-256 checksum
How to use checksums
a8e1477740bf49aef0c20d826d552a8052dbb98fb760ce02e14054ef1e016dcd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.7

Release files / mnemosynecore-1.1.8-py3-none-any.whl

Download URL mnemosynecore-1.1.8-py3-none-any.whl
Size 43.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e1c2f5d9aa79e9f4b2d56cc3d9aa757b317466146877c0be39536c6a5e1a1ede
BLAKE2b-256 checksum
How to use checksums
35fee6e48486159ca5d49674d89e2b066f4aaf023cd24b05969ba06c59deef39
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.7

Release history Release notifications | RSS feed

This release

1.1.8 This release

2 release files

1.1.7

2 release files

1.1.6

2 release files

1.1.5

2 release files

1.1.4

2 release files

1.1.3

2 release files

1.1.2

2 release files

1.1.1

2 release files

1.1.0

2 release files

1.0.3

2 release files

1.0.2

2 release files

1.0.1

2 release files

0.1.12

2 release files

0.1.10

1 release file

0.1.9

1 release file

0.1.8

1 release file

0.1.7

1 release file

0.1.6

1 release file

0.1.5

1 release file

0.1.3

1 release file

0.1.2

2 release files

0.1.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page