markup-tg-logger


Namemarkup-tg-logger JSON
Version 1.0.0 PyPI version JSON
download
home_pageNone
SummaryFlexible integration of logging module and Telegram Bot Api with HTML support
upload_time2025-07-16 18:38:52
maintainerNone
docs_urlNone
authorNone
requires_python>=3.12
licenseNone
keywords html markdown markdownv2 telegram logger logging
VCS
bugtrack_url
requirements certifi charset-normalizer idna iniconfig mypy mypy_extensions packaging pathspec pluggy Pygments pytest requests types-requests typing_extensions urllib3
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # markup-tg-logger
Flexible integration of Python's standard logging module and Telegram Bot API for logging to
Telegram chats or channels with built-in HTML support.

### Features
- Sending messages to multiple chats from a single handler.
- Ability to format log messages, `fmt` strings, stack and traceback output, or the final output.
- Full built-in HTML support. Extensible for Markdown and MarkdownV2 usage.
- Splitting long log entries into multiple messages that don't exceed Telegram's character limit
while maintaining valid markup during splitting.
- Configurable escaping of markup special characters at different formatting stages.
- Configurable notification disabling based on log level or other parameters.
- Choice of HTTP client library for Telegram Bot API interaction: `http.client` or `requests`.
  Option to install the library without dependencies.
- The library is fully documented in docstrings.

## Table of Contents
- [Installation](#installation)
- [Quick Start](#quick-start)
    - [Minimal Example](#minimal-example)
    - [Using HTML Markup](#using-html-markup)
        - [Escaping](#escaping)
        - [Templates](#templates)
        - [Level Names](#level-names)
        - [Binding with Handler](#binding-with-handler)
    - [Notification Settings](#notification-settings)
    - [Splitting Long Texts](#splitting-long-texts)
    - [API Adapters](#api-adapters)
    - [Code of the given examples](#code-of-the-given-examples)
- [Documentation](#documentation)
    - [Structure](#structure)
    - [Markdown Support](#markdown-support)
- [Testing](#testing)
- [Useful Links](#useful-links)
- [Feedback](#feedback)

## Installation

Requires Python version 3.12+, 3.13 recommended.

Installation without dependencies:

```bash
pip install markup-tg-logger
```

Installation with `requests` library:

```bash
pip install markup-tg-logger[requests]
```

Import:

```python
import markup_tg_logger
```

## Quick Start

Basic knowledge of Python's standard `logging` library is recommended to work with this library.  
[Python logging Docs](https://docs.python.org/3/library/logging.html#module-logging)

### Minimal Example

`TelegramHandler` sends messages to a chat or channel via a Telegram bot. At minimum, you only
need to provide the bot token and the chat ID where logs will be sent.

```python
import logging

from markup_tg_logger import TelegramHandler


handler = TelegramHandler(
    bot_token = 'bot_token',
    chat_id = 12345,
)
handler.setLevel(logging.INFO)

logger = logging.getLogger('example')
logger.setLevel(logging.DEBUG)
logger.addHandler(handler)

logger.info('This message sended via markup-tg-logger')
```

You can also specify multiple recipients in `chat_id`, for example: `chat_id = {12345, '@logchannel'}`.

For private messages, `chat_id` is the same as `user_id`, which can be obtained through the Bot API.
For instance, you can use one of the currently available bots at the time of writing:   
[Show Json Bot](https://t.me/ShowJsonBot).

### Using HTML Markup

To control markup, configure and set the appropriate formatter in the handler. For most tasks,
`HtmlFormatter` is sufficient. In the following example, HTML is used in the `fmt` string.

```python
from markup_tg_logger import HtmlFormatter

FMT = (
    '<b>{levelname}</b>\n\n'
    '<u>{asctime}</u>\n\n'
    '<i>{message}</i>\n\n'
    '(Line: {lineno} [<code>{pathname}</code>])'
)

formatter = HtmlFormatter(
    fmt = FMT,
    datefmt = '%d-%m-%Y %H:%M:%S',
    style = '{',
)
```

For more details about HTML in Telegram, read
[Bot API documentation](https://core.telegram.org/bots/api#html-style).

#### Escaping

By default, message text is escaped. If you want to use markup directly when calling the logger
(`logger.info('<code>example</code>')`), set the `escape_message=False` parameter in the
constructor of `HtmlFormatter`.

It's recommended to keep `escape_stack_info` and `escape_exception` parameters enabled, as stack
and traceback outputs typically contain `<` and `>` characters by default.

#### Templates

You can also wrap stack and/or traceback outputs in HTML templates. For this, specify
`stack_info_template` and `exception_template` parameters with a string like `<tag>{text}</tag>`.

Commonly used templates include:
- Monospace font: `<code>{text}</code>`
- Syntax-highlighted code block: `<pre><code class="language-python">{text}</code></pre>`

For convenience, you can import ready-made templates for Python and Bash code blocks:

```python
from markup_tg_logger.defaults import HTML_PYTHON_TEMPLATE, HTML_BASH_TEMPLATE
```

Alternatively, you can wrap the entire logger output in an HTML template using the `result_template`
parameter. In this case, the formatter will fully format the text (similar to standard
`logging.Formatter`), including stack and traceback outputs, and then insert the formatted text
into the specified template. It's recommended to enable `escape_result` and disable other `escape_*`
flags in this scenario.

#### Level Names

Telegram allows using emojis in messages, so by default level names are replaced with colored
emojis for better visual distinction between messages.

⬛️ - DEBUG   
⬜️ - INFO   
🟨 - WARNING   
🟥 - ERROR   
🟪 - CRITICAL   

You can override level names using the `level_names` parameter:

```python
formatter = HtmlFormatter(
    ...
    level_names = {logging.DEBUG: '⬛⬛️⬛️', logging.INFO: '⬜️⬜️⬜️'}
)
```

Levels not explicitly specified in the dictionary will keep their default names from the original
library. To reset all names to default, specify `level_names = {}`.

#### Binding with Handler

After configuring the formatter, set it to the `TelegramHandler` instance:

```python
...
handler.setFormatter(formatter)
```

### Notification Settings

You can enable or disable message notifications when creating the handler. This parameter is taken
directly from the Telegram Bot API. Notifications are enabled by default.

```python
handler = TelegramHandler(
    bot_token = 'bot_token',
    chat_id = 12345,
    disable_notification = True,
)
```

For more flexible configuration, you can pass an implementation of the `INotifier` interface to
`disable_notification` to control notifications. The library includes a ready-made `LevelNotifier`
class for enabling notifications when certain log levels are reached.

```python
from markup_tg_logger import LevelNotifier

handler = TelegramHandler(
    ...
    disable_notification = LevelNotifier(logging.ERROR),
)
```

### Splitting Long Texts

Telegram supports messages up to 4096 characters. Log entries may exceed this limit, especially
with long tracebacks. By default, `TelegramHandler` is configured to automatically split long texts
into multiple messages while preserving markup in each message.

To override this behavior, pass a reconfigured splitter factory to `message_splitter_factory`.

```python
from markup_tg_logger import MessageSplitterFactory
from markup_tg_logger.interfaces import IMessageSplitter

class CustomHtmlSplitter(IMessageSplitter):
    ...

handler = TelegramHandler(
    ...
    message_splitter_factory = MessageSplitterFactory({'HTML': CustomHtmlSplitter})
)
```

### API Adapters

You can choose an HTTP client for interacting with Telegram Bot API to better integrate with your
project's dependencies, or implement your own `ITelegramSender`.

Currently, the library includes implementations using:
- Python's standard `http.client`
- The popular third-party `requests` library

If the `requests` library is installed, `TelegramHandler` will use it by default automatically.

For more control, you can pass a sender instance to the `sender` parameter
when creating `TelegramHandler`.

```python
from markup_tg_logger import TelegramHandler
from markup_tg_logger.telegram_senders.http_client import HttpClientTelegramSender


handler = TelegramHandler(
    ...
    sender = HttpClientTelegramSender(),
)
```

### Code of the given examples

[Code for the examples shown](https://github.com/korandr/markup-tg-logger/tree/main/src/examples)

To run, set `BOT_TOKEN` and `CHAT_ID` environment variables.

## Documentation

The library is fully documented in docstrings.

### Structure

`markup_tg_logger/`
- `formatters/` - Classes based on `logging.Formatter`.
- `interfaces/` - Library interfaces for implementing custom classes.
- `message_splitters/` - Classes that split text with markup into messages
that do not exceeda given length.
- `notifiers/` - Classes that decide whether to turn on notifications in Telegram
depending on the `LogRecord` parameters.
- `telegram_senders/` - Classes that interact with the Telegram API.
Adapters for different HTTP libraries.
- `config.py` - Immutable data for the library.
- `defaults.py` - Some pre-configured values for class constructor parameters.
- `exceptions.py` - All library exceptions.
- `handler.py` - The central library class based on `logging.Handler`.
- `types.py` - Custom data types.

### Markdown Support

The library provides a built-in implementation for working with HTML only, but also provides an
interface-based API for implementing other markup languages.

For full Markdown support, `MarkdownMessageSplitter` should be implemented based on
`IMessageSplitter` to split messages while preserving markup.

```python
from markup_tg_logger import (
    TelegramHandler, EscapeMarkupFormatter,
    MessageSplitterFactory, BaseMessageSplitter, HtmlMessageSplitter,
)
from markup_tg_logger.interfaces import IMessageSplitter
from markup_tg_logger.types import ParseMode


class MarkdownMessageSplitter(IMessageSplitter):
    @property
    def parse_mode(self) -> ParseMode:
        return 'Markdown'
    
    def split(self, text: str) -> list[str]:
        ...

message_splitter_factory = MessageSplitterFactory(
    parse_mode_to_splitter = {
        '': BaseMessageSplitter(),
        'HTML': HtmlMessageSplitter(),
        'Markdown': MarkdownMessageSplitter(),
    }
)

formatter = EscapeMarkupFormatter(
    ...
    parse_mode = 'Markdown',
)

handler = TelegramHandler(
    ...
    message_splitter_factory = message_splitter_factory,
)
handler.setFormatter(formatter)
```

The `BaseMarkupFormatter` and `EscapeMarkupFormatter` classes are markup language independent
and can be used for Markdown without modification.

If you know for sure that your messages will not exceed the Telegram character limit, you can
immediately use Markdown in combination with `BaseMessageSplitter`.

```python
message_splitter_factory = MessageSplitterFactory(
    parse_mode_to_splitter = {
        '': BaseMessageSplitter(),
        'HTML': HtmlMessageSplitter(),
        'Markdown': BaseMessageSplitter(),
    }
)
```

## Testing

Installing dependencies for tests:

```bash
pip install -r requirements.txt
```

Running tests from the repository root:

```bash
pytest
```

## Useful Links

- [Python logging Docs](https://docs.python.org/3/library/logging.html#module-logging)
- [Telegram - Create Bot](https://core.telegram.org/bots/features#botfather)
- [Telegram Bot API - sendMessage](https://core.telegram.org/bots/api#sendmessage)
- [Telegram Bot API - HTML](https://core.telegram.org/bots/api#html-style)
- [Show Json Bot - Get user_id](https://t.me/ShowJsonBot)

## Feedback
Developer: Andrey Korovyansky | [andrey.korovyansky@gmail.com](mailto:andrey.korovyansky@gmail.com)

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "markup-tg-logger",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.12",
    "maintainer_email": null,
    "keywords": "HTML, Markdown, MarkdownV2, Telegram, logger, logging",
    "author": null,
    "author_email": "korandr <andrey.korovyansky@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/9b/5a/69763377e1f017b0873201518899a9049c80a8222bd0cfd8608cdc794f8b/markup_tg_logger-1.0.0.tar.gz",
    "platform": null,
    "description": "# markup-tg-logger\nFlexible integration of Python's standard logging module and Telegram Bot API for logging to\nTelegram chats or channels with built-in HTML support.\n\n### Features\n- Sending messages to multiple chats from a single handler.\n- Ability to format log messages, `fmt` strings, stack and traceback output, or the final output.\n- Full built-in HTML support. Extensible for Markdown and MarkdownV2 usage.\n- Splitting long log entries into multiple messages that don't exceed Telegram's character limit\nwhile maintaining valid markup during splitting.\n- Configurable escaping of markup special characters at different formatting stages.\n- Configurable notification disabling based on log level or other parameters.\n- Choice of HTTP client library for Telegram Bot API interaction: `http.client` or `requests`.\n  Option to install the library without dependencies.\n- The library is fully documented in docstrings.\n\n## Table of Contents\n- [Installation](#installation)\n- [Quick Start](#quick-start)\n    - [Minimal Example](#minimal-example)\n    - [Using HTML Markup](#using-html-markup)\n        - [Escaping](#escaping)\n        - [Templates](#templates)\n        - [Level Names](#level-names)\n        - [Binding with Handler](#binding-with-handler)\n    - [Notification Settings](#notification-settings)\n    - [Splitting Long Texts](#splitting-long-texts)\n    - [API Adapters](#api-adapters)\n    - [Code of the given examples](#code-of-the-given-examples)\n- [Documentation](#documentation)\n    - [Structure](#structure)\n    - [Markdown Support](#markdown-support)\n- [Testing](#testing)\n- [Useful Links](#useful-links)\n- [Feedback](#feedback)\n\n## Installation\n\nRequires Python version 3.12+, 3.13 recommended.\n\nInstallation without dependencies:\n\n```bash\npip install markup-tg-logger\n```\n\nInstallation with `requests` library:\n\n```bash\npip install markup-tg-logger[requests]\n```\n\nImport:\n\n```python\nimport markup_tg_logger\n```\n\n## Quick Start\n\nBasic knowledge of Python's standard `logging` library is recommended to work with this library.  \n[Python logging Docs](https://docs.python.org/3/library/logging.html#module-logging)\n\n### Minimal Example\n\n`TelegramHandler` sends messages to a chat or channel via a Telegram bot. At minimum, you only\nneed to provide the bot token and the chat ID where logs will be sent.\n\n```python\nimport logging\n\nfrom markup_tg_logger import TelegramHandler\n\n\nhandler = TelegramHandler(\n    bot_token = 'bot_token',\n    chat_id = 12345,\n)\nhandler.setLevel(logging.INFO)\n\nlogger = logging.getLogger('example')\nlogger.setLevel(logging.DEBUG)\nlogger.addHandler(handler)\n\nlogger.info('This message sended via markup-tg-logger')\n```\n\nYou can also specify multiple recipients in `chat_id`, for example: `chat_id = {12345, '@logchannel'}`.\n\nFor private messages, `chat_id` is the same as `user_id`, which can be obtained through the Bot API.\nFor instance, you can use one of the currently available bots at the time of writing:   \n[Show Json Bot](https://t.me/ShowJsonBot).\n\n### Using HTML Markup\n\nTo control markup, configure and set the appropriate formatter in the handler. For most tasks,\n`HtmlFormatter` is sufficient. In the following example, HTML is used in the `fmt` string.\n\n```python\nfrom markup_tg_logger import HtmlFormatter\n\nFMT = (\n    '<b>{levelname}</b>\\n\\n'\n    '<u>{asctime}</u>\\n\\n'\n    '<i>{message}</i>\\n\\n'\n    '(Line: {lineno} [<code>{pathname}</code>])'\n)\n\nformatter = HtmlFormatter(\n    fmt = FMT,\n    datefmt = '%d-%m-%Y %H:%M:%S',\n    style = '{',\n)\n```\n\nFor more details about HTML in Telegram, read\n[Bot API documentation](https://core.telegram.org/bots/api#html-style).\n\n#### Escaping\n\nBy default, message text is escaped. If you want to use markup directly when calling the logger\n(`logger.info('<code>example</code>')`), set the `escape_message=False` parameter in the\nconstructor of `HtmlFormatter`.\n\nIt's recommended to keep `escape_stack_info` and `escape_exception` parameters enabled, as stack\nand traceback outputs typically contain `<` and `>` characters by default.\n\n#### Templates\n\nYou can also wrap stack and/or traceback outputs in HTML templates. For this, specify\n`stack_info_template` and `exception_template` parameters with a string like `<tag>{text}</tag>`.\n\nCommonly used templates include:\n- Monospace font: `<code>{text}</code>`\n- Syntax-highlighted code block: `<pre><code class=\"language-python\">{text}</code></pre>`\n\nFor convenience, you can import ready-made templates for Python and Bash code blocks:\n\n```python\nfrom markup_tg_logger.defaults import HTML_PYTHON_TEMPLATE, HTML_BASH_TEMPLATE\n```\n\nAlternatively, you can wrap the entire logger output in an HTML template using the `result_template`\nparameter. In this case, the formatter will fully format the text (similar to standard\n`logging.Formatter`), including stack and traceback outputs, and then insert the formatted text\ninto the specified template. It's recommended to enable `escape_result` and disable other `escape_*`\nflags in this scenario.\n\n#### Level Names\n\nTelegram allows using emojis in messages, so by default level names are replaced with colored\nemojis for better visual distinction between messages.\n\n\u2b1b\ufe0f - DEBUG   \n\u2b1c\ufe0f - INFO   \n\ud83d\udfe8 - WARNING   \n\ud83d\udfe5 - ERROR   \n\ud83d\udfea - CRITICAL   \n\nYou can override level names using the `level_names` parameter:\n\n```python\nformatter = HtmlFormatter(\n    ...\n    level_names = {logging.DEBUG: '\u2b1b\u2b1b\ufe0f\u2b1b\ufe0f', logging.INFO: '\u2b1c\ufe0f\u2b1c\ufe0f\u2b1c\ufe0f'}\n)\n```\n\nLevels not explicitly specified in the dictionary will keep their default names from the original\nlibrary. To reset all names to default, specify `level_names = {}`.\n\n#### Binding with Handler\n\nAfter configuring the formatter, set it to the `TelegramHandler` instance:\n\n```python\n...\nhandler.setFormatter(formatter)\n```\n\n### Notification Settings\n\nYou can enable or disable message notifications when creating the handler. This parameter is taken\ndirectly from the Telegram Bot API. Notifications are enabled by default.\n\n```python\nhandler = TelegramHandler(\n    bot_token = 'bot_token',\n    chat_id = 12345,\n    disable_notification = True,\n)\n```\n\nFor more flexible configuration, you can pass an implementation of the `INotifier` interface to\n`disable_notification` to control notifications. The library includes a ready-made `LevelNotifier`\nclass for enabling notifications when certain log levels are reached.\n\n```python\nfrom markup_tg_logger import LevelNotifier\n\nhandler = TelegramHandler(\n    ...\n    disable_notification = LevelNotifier(logging.ERROR),\n)\n```\n\n### Splitting Long Texts\n\nTelegram supports messages up to 4096 characters. Log entries may exceed this limit, especially\nwith long tracebacks. By default, `TelegramHandler` is configured to automatically split long texts\ninto multiple messages while preserving markup in each message.\n\nTo override this behavior, pass a reconfigured splitter factory to `message_splitter_factory`.\n\n```python\nfrom markup_tg_logger import MessageSplitterFactory\nfrom markup_tg_logger.interfaces import IMessageSplitter\n\nclass CustomHtmlSplitter(IMessageSplitter):\n    ...\n\nhandler = TelegramHandler(\n    ...\n    message_splitter_factory = MessageSplitterFactory({'HTML': CustomHtmlSplitter})\n)\n```\n\n### API Adapters\n\nYou can choose an HTTP client for interacting with Telegram Bot API to better integrate with your\nproject's dependencies, or implement your own `ITelegramSender`.\n\nCurrently, the library includes implementations using:\n- Python's standard `http.client`\n- The popular third-party `requests` library\n\nIf the `requests` library is installed, `TelegramHandler` will use it by default automatically.\n\nFor more control, you can pass a sender instance to the `sender` parameter\nwhen creating `TelegramHandler`.\n\n```python\nfrom markup_tg_logger import TelegramHandler\nfrom markup_tg_logger.telegram_senders.http_client import HttpClientTelegramSender\n\n\nhandler = TelegramHandler(\n    ...\n    sender = HttpClientTelegramSender(),\n)\n```\n\n### Code of the given examples\n\n[Code for the examples shown](https://github.com/korandr/markup-tg-logger/tree/main/src/examples)\n\nTo run, set `BOT_TOKEN` and `CHAT_ID` environment variables.\n\n## Documentation\n\nThe library is fully documented in docstrings.\n\n### Structure\n\n`markup_tg_logger/`\n- `formatters/` - Classes based on `logging.Formatter`.\n- `interfaces/` - Library interfaces for implementing custom classes.\n- `message_splitters/` - Classes that split text with markup into messages\nthat do not exceeda given length.\n- `notifiers/` - Classes that decide whether to turn on notifications in Telegram\ndepending on the `LogRecord` parameters.\n- `telegram_senders/` - Classes that interact with the Telegram API.\nAdapters for different HTTP libraries.\n- `config.py` - Immutable data for the library.\n- `defaults.py` - Some pre-configured values for class constructor parameters.\n- `exceptions.py` - All library exceptions.\n- `handler.py` - The central library class based on `logging.Handler`.\n- `types.py` - Custom data types.\n\n### Markdown Support\n\nThe library provides a built-in implementation for working with HTML only, but also provides an\ninterface-based API for implementing other markup languages.\n\nFor full Markdown support, `MarkdownMessageSplitter` should be implemented based on\n`IMessageSplitter` to split messages while preserving markup.\n\n```python\nfrom markup_tg_logger import (\n    TelegramHandler, EscapeMarkupFormatter,\n    MessageSplitterFactory, BaseMessageSplitter, HtmlMessageSplitter,\n)\nfrom markup_tg_logger.interfaces import IMessageSplitter\nfrom markup_tg_logger.types import ParseMode\n\n\nclass MarkdownMessageSplitter(IMessageSplitter):\n    @property\n    def parse_mode(self) -> ParseMode:\n        return 'Markdown'\n    \n    def split(self, text: str) -> list[str]:\n        ...\n\nmessage_splitter_factory = MessageSplitterFactory(\n    parse_mode_to_splitter = {\n        '': BaseMessageSplitter(),\n        'HTML': HtmlMessageSplitter(),\n        'Markdown': MarkdownMessageSplitter(),\n    }\n)\n\nformatter = EscapeMarkupFormatter(\n    ...\n    parse_mode = 'Markdown',\n)\n\nhandler = TelegramHandler(\n    ...\n    message_splitter_factory = message_splitter_factory,\n)\nhandler.setFormatter(formatter)\n```\n\nThe `BaseMarkupFormatter` and `EscapeMarkupFormatter` classes are markup language independent\nand can be used for Markdown without modification.\n\nIf you know for sure that your messages will not exceed the Telegram character limit, you can\nimmediately use Markdown in combination with `BaseMessageSplitter`.\n\n```python\nmessage_splitter_factory = MessageSplitterFactory(\n    parse_mode_to_splitter = {\n        '': BaseMessageSplitter(),\n        'HTML': HtmlMessageSplitter(),\n        'Markdown': BaseMessageSplitter(),\n    }\n)\n```\n\n## Testing\n\nInstalling dependencies for tests:\n\n```bash\npip install -r requirements.txt\n```\n\nRunning tests from the repository root:\n\n```bash\npytest\n```\n\n## Useful Links\n\n- [Python logging Docs](https://docs.python.org/3/library/logging.html#module-logging)\n- [Telegram - Create Bot](https://core.telegram.org/bots/features#botfather)\n- [Telegram Bot API - sendMessage](https://core.telegram.org/bots/api#sendmessage)\n- [Telegram Bot API - HTML](https://core.telegram.org/bots/api#html-style)\n- [Show Json Bot - Get user_id](https://t.me/ShowJsonBot)\n\n## Feedback\nDeveloper: Andrey Korovyansky | [andrey.korovyansky@gmail.com](mailto:andrey.korovyansky@gmail.com)\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "Flexible integration of logging module and Telegram Bot Api with HTML support",
    "version": "1.0.0",
    "project_urls": {
        "Documentation": "https://github.com/korandr/markup-tg-logger",
        "Github": "https://github.com/korandr/markup-tg-logger"
    },
    "split_keywords": [
        "html",
        " markdown",
        " markdownv2",
        " telegram",
        " logger",
        " logging"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "a5e4a0a60128e2ca60d06b6692a3e380070a6dd7b4ab106ec9974a4231e8dec9",
                "md5": "cb7f20e127ae8cf999a34b9dc6699e17",
                "sha256": "52b7b7067f3ea4ea8574063543dba7bb6b9883314adbd0fee54aade60fad112e"
            },
            "downloads": -1,
            "filename": "markup_tg_logger-1.0.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "cb7f20e127ae8cf999a34b9dc6699e17",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.12",
            "size": 27726,
            "upload_time": "2025-07-16T18:38:50",
            "upload_time_iso_8601": "2025-07-16T18:38:50.819248Z",
            "url": "https://files.pythonhosted.org/packages/a5/e4/a0a60128e2ca60d06b6692a3e380070a6dd7b4ab106ec9974a4231e8dec9/markup_tg_logger-1.0.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "9b5a69763377e1f017b0873201518899a9049c80a8222bd0cfd8608cdc794f8b",
                "md5": "7c4636cc9f8a5272d7297a5a8e976ed8",
                "sha256": "042090dc22b1c20e2023c00be47fce2539fa4be4699988b06160fa0329dca0a3"
            },
            "downloads": -1,
            "filename": "markup_tg_logger-1.0.0.tar.gz",
            "has_sig": false,
            "md5_digest": "7c4636cc9f8a5272d7297a5a8e976ed8",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.12",
            "size": 29841,
            "upload_time": "2025-07-16T18:38:52",
            "upload_time_iso_8601": "2025-07-16T18:38:52.209568Z",
            "url": "https://files.pythonhosted.org/packages/9b/5a/69763377e1f017b0873201518899a9049c80a8222bd0cfd8608cdc794f8b/markup_tg_logger-1.0.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-07-16 18:38:52",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "korandr",
    "github_project": "markup-tg-logger",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "requirements": [
        {
            "name": "certifi",
            "specs": [
                [
                    "==",
                    "2025.7.14"
                ]
            ]
        },
        {
            "name": "charset-normalizer",
            "specs": [
                [
                    "==",
                    "3.4.2"
                ]
            ]
        },
        {
            "name": "idna",
            "specs": [
                [
                    "==",
                    "3.10"
                ]
            ]
        },
        {
            "name": "iniconfig",
            "specs": [
                [
                    "==",
                    "2.1.0"
                ]
            ]
        },
        {
            "name": "mypy",
            "specs": [
                [
                    "==",
                    "1.17.0"
                ]
            ]
        },
        {
            "name": "mypy_extensions",
            "specs": [
                [
                    "==",
                    "1.1.0"
                ]
            ]
        },
        {
            "name": "packaging",
            "specs": [
                [
                    "==",
                    "25.0"
                ]
            ]
        },
        {
            "name": "pathspec",
            "specs": [
                [
                    "==",
                    "0.12.1"
                ]
            ]
        },
        {
            "name": "pluggy",
            "specs": [
                [
                    "==",
                    "1.6.0"
                ]
            ]
        },
        {
            "name": "Pygments",
            "specs": [
                [
                    "==",
                    "2.19.2"
                ]
            ]
        },
        {
            "name": "pytest",
            "specs": [
                [
                    "==",
                    "8.4.1"
                ]
            ]
        },
        {
            "name": "requests",
            "specs": [
                [
                    "==",
                    "2.32.4"
                ]
            ]
        },
        {
            "name": "types-requests",
            "specs": [
                [
                    "==",
                    "2.32.4.20250611"
                ]
            ]
        },
        {
            "name": "typing_extensions",
            "specs": [
                [
                    "==",
                    "4.14.1"
                ]
            ]
        },
        {
            "name": "urllib3",
            "specs": [
                [
                    "==",
                    "2.5.0"
                ]
            ]
        }
    ],
    "lcname": "markup-tg-logger"
}
        
Elapsed time: 0.48051s