Catalog PyPI
PACKAGE EXPLORERView in registry

2m

PyPI

UI integration package

Versions collected1
Direct dependencies9From release 1.2.5
Last observed20 Oct, 15:26 UTC

README

Version 1.2.5 documentation

intro abc replication search-nodes append-node push-queue stack-example



Quickstart guide

Инициализация

> pip install 2m

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

> cd ../path_to_your_ui

Устанавливаем зависимые пакеты, сверяем соответствие, развёртываем пакет с модулями:

> python -c "from two_m_root.install import install;exec(install.main())"

install

Теперь в вашем текущем покете появился пакет two_m, содержащий несколько модулей, которые необходимо настроить.


Настройка

  • Опишем свои таблицы в models.py

Обращаю ваше внимание на официальную документацию Flask-SQLAlchemy https://flask-sqlalchemy.readthedocs.io/en/stable/legacy-quickstart/#define-models

  • procedures.py

Если нужно работать с хранимыми процедурами, декларируем их в виде экземпляров класса DDL.

Документация SqlAlchemy относительно объектов DDL https://docs.sqlalchemy.org/en/20/core/ddl.html#custom-ddl

  • Настроим .env файл, содержащий константы, которые конфигурируют работу базы данных и локального хранилища

settings

После написания таблиц в models и хранимых процедур в procedures, нужно инициализировать их в базу даных.

> python -c "from two_m.models import create_db;create_db()"

> python -c "from two_m.procedures import init_procedures;init_procedures()"

  • Наконец, можно приступить к использованию! Импортируем класс Tool и начнём работу!
from two_m_root.core import Tool
from two_m.models import SomeModel
...
...
...
class Something:
    def __init__():
        self.tool = Tool()
        self.tool.set_model(SomeModel)

    def ui_action_a():
        self.tool.set_item(...)

    def ui_action_b():
        self.tool.set_item(...)

    def ui_action_b():
        items = self.tool.get_items(...)
        ...

Рассмотрим функционал, который является основной компетенций данного фреймворка

  • orm.set_item(_model=None, _ready=False, _insert=False, _update=False, _delete=False, _where=None, **values)

Установить в очередь запись-кандидата, которая появится в базе данных при первой возможности

    • _model: Таблица из модуля models.py. Можно не указывать, если в текущем контексте (вашего приложения) уже установлена таблица в качестве основной (смотри класс ORM, метод set_model)
    • _ready: Логическое значение. До тех пор, пока это значение False, нода будет находиться в очереди, но commit базы данных не попадёт. Идеальный способ передавать ответ от вашего валидатора
    • _insert, _update, _delete: Логическое значение. DML-SQL
    • _where: Словарь вида column_name:value для выражения where
    • return None

Пример: пользовательская функция-валидатор даёт ответ, готова ли данная запись на транзакцию во "внешний мир":

is_ready

  • orm.get_items(_model=None, _db_only=False, _queue_only=False, **where)

    • _model: Таблица из модуля models.py. Можно не указывать, если в текущем контексте (вашего приложения) уже установлена таблица в качестве основной (смотри класс ORM, метод set_model)
    • _db_only: Получать данные только из базы данных, игнорируя локальные элементы
    • _queue_only: Получать данные только из локальной очереди элементов, игнорируя базу данных
    • return Result
  • orm.join_select(*models, _db_only=False, _queue_only=False, _on=None, **where)

    • models: Таблицы из модуля models.py между которыми существует отношение (PK-FK)
    • _db_only: Получать данные только из базы данных, игнорируя локальные элементы
    • _queue_only: Получать данные только из локальной очереди элементов, игнорируя базу данных
    • _on: Словарь. Выражение ON в JOIN запросах. modelName.column1: modelName2.column2
    • return JoinSelectResult

Несколько слов о принципе работы внутренних механизмов, которые объединяют воедино записи из удалённого расположения (базы данных), и записи из локального хранилища. Рассмотрим 1 строку из таблицы А и 1 строку из таблицы B, чтобы понять, как будет происходить слияние.

  1. Обе записи в отношениях (PRIMARY_KEY - FOREIGN KEY) находятся в локальном расположении Все записи в кеше
  2. Запись из базы данных (PRIMARY_KEY), а запись, которая на неё ссылается (FOREIGN KEY) находится в локальном хранилище Основная запись в бд, зависимая в кеше
  3. Нетипичный случай, когда пользователь установил в столбец (FOREIGN KEY) значение, первичный ключ от этого не нашёлся ни среди элементов из базы данных, ни в локальных. В этом случае будут получены обе записи в отношениях (PRIMARY_KEY - FOREIGN KEY) из базы данных, если таковые имеются; В противном случае этой записи не будет в результатах Ошибка внешнего ключа

BaseResult

Union[Result, JoinSelectResult]

Он же

Объект результата

Объекты результата, производные от класса BaseResult, возвращаемые методами orm.get_items и orm.join_select соответственно, являются ЛЕНИВЫМИ объектами, то есть не содержат никакого результата явным образом, но хранят в себе все детали запроса. При каждом взаимодействии с итератором, contains, getitem, bool, len и даже str, происходит новый запрос.

: - Что это, зачем, - зачем усложнять? Ведь можно написать запрос и получить ответ: здесь и сейчас :question:


Во-первых, я нахожу весьма удобным не писать отдельных пользовательских функций для мемоизации параметров запроса, чтобы потом возвращаться к этому снова и снова, заполняя своё приложение потенциально лишним кодом.
Во-вторых, "под капотом" скрывается достаточно хитрая система, которая, если описать это просто, делает следующее:

  1. Извлекает записи из базы данных
  2. Извлекает записи из локальной базы данных
  3. Реплицирует одно на другое: на записи из базы данных накладываются записи, которые хранятся локально, и, по тем или иным причинам, пока ещё не закоммитились.


В-третьих, эти ленивые экземпляры дают большое количество синтаксического сахара, который, по заветам pythonicway, избавит ваш интерфейс от каждой лишней строчки!

  • has_changes(hash_value=None) -> Optional[bool]

Просто обратимся к экземпляру, чтобы узнать, есть ли изменения в данных: has_changes Если значение хеш-суммы никогда не фигурировало в рамках текущего экземпляра результата, вернёт - None.

  • has_new_entries

Также, можно с лёгкостью узнать, появились ли новые (или стали недоступны те, что получены) записи: has_new_entries

Result

Объект запроса к 1 таблице.

  • items - property - ResultORMCollection
  • iter - ResultORMCollection._ iter _()
  • visible_items - property - ResultORMCollection. Только ноды с атрибутом 'ui_hidden': False в словаре value.
  • bool - True, если есть хотя бы 1 результат, иначе False
  • len - От количества ResultORMItem в ResultORMCollection
  • getitem - Вернёт новый экземпляр ResultORMCollection с одним или несколькими ResultORMItem по:
  1. Индексу (порядковый номер в коллекции, начиная с 0)
  2. Хеш-сумме пары ключ-значение у ResultORMItem. См свойство hash_by_pk
  3. Полной хеш сумме ResultORMItem
  4. Названию таблицы
  • contains - Поддерживается возможность проверки содержания следующих типов:
  1. ResultORMItem
  2. Индекс в коллекции - int
  3. Название таблицы - str
  4. Хеш-сумма от ResultORMItem - int
  5. Хеш-сумма первичного ключа+значения. Можно получить через ResultORMItem.hash_by_pk - int
  • hash - Получить полную хеш-сумму всех значений в словаре значений каждого экземпляра ResultORMItem, в рамках текущего экземпляра контейнера - ResultORMCollection
  • pointer - (property) геттер и сеттер для инициализации Pointer

JoinSelectResult

Объект запроса к нескольким таблицам. В рамках результирующего списка каждый ResultORMCollection представляет внутри себя связку PK-FK.

  • items - property - tuple(ResultORMCollection)
  • iter - tuple(ResultORMCollection)._ _ iter_ _()
  • visible_items - property - кортеж ResultORMCollection. Если в одной из нод, в рамках одной группы нод, имеют 'ui_hidden': True в словаре value, то данная группа будет скрыта из результатов.
  • bool - True, если в списке есть хотя бы 1 результат ResultORMCollection, иначе False
  • len - От количества ResultORMCollection в кортеже результатов
  • getitem - Вернёт новый экземпляр ResultORMCollection по одному из следующих способов:
  1. Индекс в результирующем кортеже - int
  2. Хеш-сумма hash(sum(map(...ResultORMCollection)))
  3. Хеш-сумма первичных ключей+значений внутри ResultORMCollection - int
  • contains - Поддерживается возможность проверки содержания следующих типов:
  1. ResultORMCollection
  2. ResultORMItem
  3. hash_sum - int
  4. Хеш-сумма первичных ключей+значений из всех элементов внутри ResultORMCollection. Можно получить через ResultORMCollection.hash_by_pk - свойство(property) - int
  • hash - сумма всех ResultORMCollection._ hash _() в результирующем списке
  • pointer - (property) геттер и сеттер для инициализации Pointer

Pointer

Ассоциируйте строку, представляющую данные, со ссылкой на получение этих данных. Работает как для запросов к 1 таблице, так и для запросов к нескольким таблицам одновременно.

Экземпляр Pointer инкапсулируется в экземпляр результата и предназначен для чтения только по свойству, - не следует пытаться сделать на него ещё одну ссылку :rage:

Инициализация

any_result.pointer = ["список", "совпадающий", "по", "длине", "с", "содержимым"]
Каждый элемент этого списка будет ассоциирован с содержимым внутри результата 1 к 1.

Использование

  • getitem
    any_result.pointer["содержимым"] - получить [-1] элемент
    any_result.pointer["список"] - получить [0] элемент
    any_result.pointer["совпадающий"] - получить [1] элемент
    И так далее...
  • contains
    "длине" in any_result.pointer # True
    "strstr" in any_result.pointer # False
    "с" in any_result.pointer # True
    "совпадающий" in any_result.pointer # True

  • any_result.pointer.has_changes(name: str) -> Optional[bool] - Передаём сюда полную хеш сумму и получаем ответ на вопрос: есть ли какие-нибудь изменения (с момента последнего вопрошания или инициализации).
    Если переданного значения не было в списке при инициализации, вернёт None.

any_result.pointer.is_valid() -> bool. Узнать о текущем состоянии текущего экземпляра Pointer: закрылся он или нет.

  • any_result.pointer.wrap_items -> list. Исходный список строк. Если данный Pointer закрыт, список будет пустым.
  • any_result.pointer.items -> Полный словарь содержимого в виде:
    {"одна_из_строк_wrap": контейнер_с_содержимым}
  • any_result.pointer.replace_wrap(item: str, old_wrapper: Optional[str] = None, hash_: Optional[int] = None, primary_key_hash: Optional[int] = None, index: Optional[int] = None) -> None. Заменить строку указатель на новую.
    • item: Новая строка
    • old_wrapper: Старая строка из wrap_items
    • hash_: Полная хеш сумма результата, у которой следует заменить строку-указатель
    • primary_key_hash: Хеш-сумма первичного ключа и значения результата, у которого следует заменить строку-указатель
    • index: Индекс записи в результате, у которой следует заменить строку-указатель

Инвалидация

И всё было бы хорошо, но как только из базы данных придёт результат количественно другой, или, с записями, которые содержат другие первичные ключи; Если то же самое произойдет и со стороны локальных элементов,- объект сразу же откажется сотрудничать с вами. Всеми своими методами он будет отвечать - None. Всё что можно сделать в этой ситуации - создать новый :)



Содержимое результата

Union[ResultORMCollection, ResultORMItem]

Контейнер ResultORMCollection

Контейнеры с данными, возвращаемый объектом результата - Result или JoinSelectResult. Иммутабелен.

  • ResultORMCollection - композиция из ResultORMItem.

    В коллекции нод результата предусмотрена возможность установить/удалить префикс с названием таблицы в каждый столбец. Это может оказаться полезным при разработке UI.
    • prefix - свойство(property). Возвращает литерал, указывающий на текущую конфигурацию относительно префиксов: "auto", "add", "no-prefix"
    • add_model_name_prefix - Метод(callable). Установить всем столбцам значений, находящихся в каждом ResultORMItem, префикс с названием таблицы
    • remove_model_name_prefix - Метод(callable). Удалить префикс с названием таблицы из каждого значения каждого ResultORMItem
    • auto_model_name_prefix - Метод(callable). Если какой-либо столбец(его название) повторяется в каком-либо ResultORMItem текущего контейнера, то добавить префикс, иначе не добавлять
    • all_nodes - Итератор со всеми ResultORMItem. Он возвращает все ноды, включая те, которые находятся в очереди и должны сделать delete в базе данных.

Призываю не использовать метод all_nodes, он нужен для служебного пользования :rage:

    • get_node(model, primary_key, value) - Получить ResultORMItem или Exception
    • search_nodes(model, **столбцы_и_значения) - Получить коллекцию ResultORMItem или пустую коллекцию
    • hash - Получить полную хеш-сумму всех значений в словаре значений каждого экземпляра ResultORMItem, в рамках текущего экземпляра контейнера - ResultORMCollection
    • hash_by_pk - свойство(property). Получить хеш-сумму всех первичных ключей и их значений у всех ResultORMItem, в рамках текущего экземпляра контейнера - ResultORMCollection
    • iter - Итератор со всеми ResultORMItem исключая те, под которыми скрываются пустые - которые должны удалить запись из базы данных
    • bool - На основе количества элементов из iter
    • getitem - Вернёт новый экземпляр ResultORMCollection с одним или несколькими ResultORMItem по:
  1. Индексу (порядковый номер в коллекции, начиная с 0)
  2. Хеш-сумме пары ключ-значение у ResultORMItem. См свойство hash_by_pk
  3. Полной хеш сумме ResultORMItem
  4. Названию таблицы
    • contains - Поддерживается возможность проверки содержания следующих типов:
  1. ResultORMItem
  2. Индекс в коллекции - int
  3. Название таблицы - str
  4. Хеш-сумма от ResultORMItem - int
  5. Хеш-сумма первичного ключа+значения. Можно получить через ResultORMItem.hash_by_pk - int

Единица результата ResultORMItem

    • value - свойство(property) - Словарь с содержимым в виде {столбец: значение}
    • hidden - свойство(property) - Скрыт ли элемент из набора результатов
    • model - свойство(property) - Таблица текущего элемента
    • hash_by_pk - свойство(property). Хеш-сумма первичного ключа и значения
    • get(def_value=None) - Тот же getitem, но с возможностью получить значение по умолчанию
    • get_primary_key_and_value(only_key=False, only_val=False) - Словарь. Пара {столбец: значение}. Или что-то одно
    • add_model_name_prefix - Метод(callable). Добавить каждому ключу в словаре value префикс с названием таблицы
    • remove_model_name_prefix - Метод(callable). Удалить префиксы
    • hash - Получить полную хеш-сумму всех значений в словаре значений
    • contains - 2 варианта использования:
  1. строка вида имя_столбца:значение
  2. просто имя столбца
    • getitem - Получить значение столбца по его наименованию value = node["table_column"]
    • bool - От длины словаря value


Тестовый проект

Пример конфигурации с моделями, хранимыми процедурами(триггерами) и тестами!

Postgresql в качестве базы данных

tests



Changelog

1.1

  • Pointer

    Добавлен метод replace_wrap. wrap_items теперь список, а не кортеж. Более мягкое поведение относительно возбуждения WrapperLengthException, если данных нет. pymemcache.RetryingClient вместо pymemcache.Client в свойстве Tool.cache.

    Отказ от идеи наследования класса Tool в пользовательский пакет two_m, модуль main. Напротив, из two_m.main теперь импортируются константы в two_m_root.core.

1.2

Result.order_by(...), JoinSelectResult.order_by(...)

  • Result и JoinSelectResult получили метод order_by от миксина OrderByMixin Сортировка возможна по длине строк, времени добавления, или в алфавитном порядке. По любому столбцу в таблице или просто по первичному ключу.

    Пример использования:

    1. Инициализируем объект Result или JoinSelectResult с интересующими нас параметрами.

    lazy_result = my_tool_instance.get_items(table_name, ...)

    1. Вызываем метод order_by, передавая один или несколько параметров.

    lazy_result.order_by(...)

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

    Экземплярам класса Result и JoinSelectResult добавлены методы:

    • visible_items (property) - Получить экземпляр ResultORMCollection, содержащем ноды с _delete=True в значениях (они должны удалить запись)
    • hidden_items (property) - Получить экземпляр ResultORMCollection содержащий только скрытые ноды

    BaseResult получил константу ITER_ONLY_VISIBLE_ITEMS_AS_DEFAULT, определяющую поведение относительно скрытых нод. Обратим внимание, что это, в свою очередь, затрагивает работу Pointer.

  • ConnectionManager

    Все соединения с внешними сервисами вынесены в отдельный класс. Открытые подключения закрываются по таймерам, не засоряя пул. Можно настроить срок жизни подключения.

Downloads & popularity

1downloads
1-day window · source-reported counts16 Oct 2026
115.50
2026-07-20: 4 · observed 2026-10-20T16:21:42.6225585Z · period 2026-07-20–2026-07-202026-07-21: 2 · observed 2026-10-20T16:21:42.6225585Z · period 2026-07-21–2026-07-212026-07-22: 3 · observed 2026-10-20T16:21:42.6225585Z · period 2026-07-22–2026-07-222026-07-23: 1 · observed 2026-10-20T16:21:42.6225585Z · period 2026-07-23–2026-07-232026-07-24: 1 · observed 2026-10-20T16:21:42.6225585Z · period 2026-07-24–2026-07-242026-07-25: 1 · observed 2026-10-20T16:21:42.6225585Z · period 2026-07-25–2026-07-252026-07-27: 2 · observed 2026-10-20T16:21:42.6225585Z · period 2026-07-27–2026-07-272026-07-28: 1 · observed 2026-10-20T16:21:42.6225585Z · period 2026-07-28–2026-07-282026-07-29: 11 · observed 2026-10-20T16:21:42.6225585Z · period 2026-07-29–2026-07-292026-07-30: 2 · observed 2026-10-20T16:21:42.6225585Z · period 2026-07-30–2026-07-302026-08-01: 2 · observed 2026-10-20T16:21:42.6225585Z · period 2026-08-01–2026-08-012026-08-02: 1 · observed 2026-10-20T16:21:42.6225585Z · period 2026-08-02–2026-08-022026-08-03: 3 · observed 2026-10-20T16:21:42.6225585Z · period 2026-08-03–2026-08-032026-08-04: 4 · observed 2026-10-20T16:21:42.6225585Z · period 2026-08-04–2026-08-042026-08-06: 1 · observed 2026-10-20T16:21:42.6225585Z · period 2026-08-06–2026-08-062026-08-11: 1 · observed 2026-10-20T16:21:42.6225585Z · period 2026-08-11–2026-08-112026-08-13: 3 · observed 2026-10-20T16:21:42.6225585Z · period 2026-08-13–2026-08-132026-08-14: 3 · observed 2026-10-20T16:21:42.6225585Z · period 2026-08-14–2026-08-142026-08-15: 1 · observed 2026-10-20T16:21:42.6225585Z · period 2026-08-15–2026-08-152026-08-16: 1 · observed 2026-10-20T16:21:42.6225585Z · period 2026-08-16–2026-08-162026-08-17: 3 · observed 2026-10-20T16:21:42.6225585Z · period 2026-08-17–2026-08-172026-08-18: 10 · observed 2026-10-20T16:21:42.6225585Z · period 2026-08-18–2026-08-182026-08-19: 1 · observed 2026-10-20T16:21:42.6225585Z · period 2026-08-19–2026-08-192026-08-20: 1 · observed 2026-10-20T16:21:42.6225585Z · period 2026-08-20–2026-08-202026-08-22: 1 · observed 2026-10-20T16:21:42.6225585Z · period 2026-08-22–2026-08-222026-08-23: 4 · observed 2026-10-20T16:21:42.6225585Z · period 2026-08-23–2026-08-232026-08-24: 9 · observed 2026-10-20T16:21:42.6225585Z · period 2026-08-24–2026-08-242026-08-28: 1 · observed 2026-10-20T16:21:42.6225585Z · period 2026-08-28–2026-08-282026-08-31: 3 · observed 2026-10-20T16:21:42.6225585Z · period 2026-08-31–2026-08-312026-09-01: 1 · observed 2026-10-20T16:21:42.6225585Z · period 2026-09-01–2026-09-012026-09-03: 2 · observed 2026-10-20T16:21:42.6225585Z · period 2026-09-03–2026-09-032026-09-05: 1 · observed 2026-10-20T16:21:42.6225585Z · period 2026-09-05–2026-09-052026-09-07: 2 · observed 2026-10-20T16:21:42.6225585Z · period 2026-09-07–2026-09-072026-09-09: 2 · observed 2026-10-20T16:21:42.6225585Z · period 2026-09-09–2026-09-092026-09-10: 2 · observed 2026-10-20T16:21:42.6225585Z · period 2026-09-10–2026-09-102026-09-12: 2 · observed 2026-10-20T16:21:42.6225585Z · period 2026-09-12–2026-09-122026-09-16: 1 · observed 2026-10-20T16:21:42.6225585Z · period 2026-09-16–2026-09-162026-09-18: 1 · observed 2026-10-20T16:21:42.6225585Z · period 2026-09-18–2026-09-182026-09-20: 1 · observed 2026-10-20T16:21:42.6225585Z · period 2026-09-20–2026-09-202026-09-24: 2 · observed 2026-10-20T16:21:42.6225585Z · period 2026-09-24–2026-09-242026-09-26: 1 · observed 2026-10-20T16:21:42.6225585Z · period 2026-09-26–2026-09-262026-09-30: 3 · observed 2026-10-20T16:21:42.6225585Z · period 2026-09-30–2026-09-302026-10-06: 2 · observed 2026-10-20T16:21:42.6225585Z · period 2026-10-06–2026-10-062026-10-07: 1 · observed 2026-10-20T16:21:42.6225585Z · period 2026-10-07–2026-10-072026-10-09: 1 · observed 2026-10-20T16:21:42.6225585Z · period 2026-10-09–2026-10-092026-10-10: 1 · observed 2026-10-20T16:21:42.6225585Z · period 2026-10-10–2026-10-102026-10-11: 2 · observed 2026-10-20T16:21:42.6225585Z · period 2026-10-11–2026-10-112026-10-13: 1 · observed 2026-10-20T16:21:42.6225585Z · period 2026-10-13–2026-10-132026-10-15: 1 · observed 2026-10-20T16:21:42.6225585Z · period 2026-10-15–2026-10-152026-10-16: 1 · observed 2026-10-20T16:21:42.6225585Z · period 2026-10-16–2026-10-16
20 Jul16 Oct

pypistats · 50 observations shown. Missing days are unknown. Source category: overall: without mirrors.

View observed values
Date / source periodValueObserved at
2026-10-16 – 2026-10-1612026-10-20T16:21:42.6225585Z
2026-10-15 – 2026-10-1512026-10-20T16:21:42.6225585Z
2026-10-13 – 2026-10-1312026-10-20T16:21:42.6225585Z
2026-10-11 – 2026-10-1122026-10-20T16:21:42.6225585Z
2026-10-10 – 2026-10-1012026-10-20T16:21:42.6225585Z
2026-10-09 – 2026-10-0912026-10-20T16:21:42.6225585Z
2026-10-07 – 2026-10-0712026-10-20T16:21:42.6225585Z
2026-10-06 – 2026-10-0622026-10-20T16:21:42.6225585Z
2026-09-30 – 2026-09-3032026-10-20T16:21:42.6225585Z
2026-09-26 – 2026-09-2612026-10-20T16:21:42.6225585Z
2026-09-24 – 2026-09-2422026-10-20T16:21:42.6225585Z
2026-09-20 – 2026-09-2012026-10-20T16:21:42.6225585Z
2026-09-18 – 2026-09-1812026-10-20T16:21:42.6225585Z
2026-09-16 – 2026-09-1612026-10-20T16:21:42.6225585Z
2026-09-12 – 2026-09-1222026-10-20T16:21:42.6225585Z
2026-09-10 – 2026-09-1022026-10-20T16:21:42.6225585Z
2026-09-09 – 2026-09-0922026-10-20T16:21:42.6225585Z
2026-09-07 – 2026-09-0722026-10-20T16:21:42.6225585Z
2026-09-05 – 2026-09-0512026-10-20T16:21:42.6225585Z
2026-09-03 – 2026-09-0322026-10-20T16:21:42.6225585Z
2026-09-01 – 2026-09-0112026-10-20T16:21:42.6225585Z
2026-08-31 – 2026-08-3132026-10-20T16:21:42.6225585Z
2026-08-28 – 2026-08-2812026-10-20T16:21:42.6225585Z
2026-08-24 – 2026-08-2492026-10-20T16:21:42.6225585Z
2026-08-23 – 2026-08-2342026-10-20T16:21:42.6225585Z
2026-08-22 – 2026-08-2212026-10-20T16:21:42.6225585Z
2026-08-20 – 2026-08-2012026-10-20T16:21:42.6225585Z
2026-08-19 – 2026-08-1912026-10-20T16:21:42.6225585Z
2026-08-18 – 2026-08-18102026-10-20T16:21:42.6225585Z
2026-08-17 – 2026-08-1732026-10-20T16:21:42.6225585Z
2026-08-16 – 2026-08-1612026-10-20T16:21:42.6225585Z
2026-08-15 – 2026-08-1512026-10-20T16:21:42.6225585Z
2026-08-14 – 2026-08-1432026-10-20T16:21:42.6225585Z
2026-08-13 – 2026-08-1332026-10-20T16:21:42.6225585Z
2026-08-11 – 2026-08-1112026-10-20T16:21:42.6225585Z
2026-08-06 – 2026-08-0612026-10-20T16:21:42.6225585Z
2026-08-04 – 2026-08-0442026-10-20T16:21:42.6225585Z
2026-08-03 – 2026-08-0332026-10-20T16:21:42.6225585Z
2026-08-02 – 2026-08-0212026-10-20T16:21:42.6225585Z
2026-08-01 – 2026-08-0122026-10-20T16:21:42.6225585Z
2026-07-30 – 2026-07-3022026-10-20T16:21:42.6225585Z
2026-07-29 – 2026-07-29112026-10-20T16:21:42.6225585Z
2026-07-28 – 2026-07-2812026-10-20T16:21:42.6225585Z
2026-07-27 – 2026-07-2722026-10-20T16:21:42.6225585Z
2026-07-25 – 2026-07-2512026-10-20T16:21:42.6225585Z
2026-07-24 – 2026-07-2412026-10-20T16:21:42.6225585Z
2026-07-23 – 2026-07-2312026-10-20T16:21:42.6225585Z
2026-07-22 – 2026-07-2232026-10-20T16:21:42.6225585Z
2026-07-21 – 2026-07-2122026-10-20T16:21:42.6225585Z
2026-07-20 – 2026-07-2042026-10-20T16:21:42.6225585Z

Versions 1

Collected releases
VersionPublishedDirect dependenciesOpen version
1.2.53 Jun 20269

Package advisories

0
No matching advisories collected

This describes our collected data; it is not a security assessment.

Repository

PENDING
filthps/2m

Shared repository data · GitHub

License detected in repository
Not collected

Metadata history

Meaningful changes
Current collected state Current

Observed since 20 Oct, 15:26 UTC

No superseded metadata states collected. Unchanged observations do not create new revisions.

Record identity

package:13b57d0ed6cd9b608791c17af47092c07754997335bae44326b7a8a996f2bbef