Metadata-Version: 2.4
Name: ix-notifiers
Version: 2.0.6
Summary: A python library for notifiers
License: MIT License
         
         Copyright (c) 2020-2025 ix.ai, egos.tech
         
         Permission is hereby granted, free of charge, to any person obtaining a copy
         of this software and associated documentation files (the "Software"), to deal
         in the Software without restriction, including without limitation the rights
         to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
         copies of the Software, and to permit persons to whom the Software is
         furnished to do so, subject to the following conditions:
         
         The above copyright notice and this permission notice shall be included in all
         copies or substantial portions of the Software.
         
         THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
         IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
         FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
         AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
         LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
         OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
         SOFTWARE.
License-File: LICENSE
Author: Alex Thomae
Author-email: notifiers@egos.tech
Requires-Python: >=3.12
Classifier: Intended Audience :: Developers
Classifier: Natural Language :: English
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: Topic :: Software Development :: Libraries
Requires-Dist: egos-helpers (==1.4.2)
Requires-Dist: requests (==2.34.2)
Project-URL: Homepage, https://gitlab.com/egos-tech/notifiers
Project-URL: Source, https://gitlab.com/egos-tech/notifiers
Description-Content-Type: text/markdown

# ix-notifiers

A python library for sending one notification to several services at once.

## Install

```sh
pip install ix-notifiers
```

## Usage

Build a core, register the notifiers you want, then send. `notify()` returns True when
at least one channel accepted the notification.

```python
from ix_notifiers import IxNotifiers

notifiers = IxNotifiers()

# Each keyword is prefixed with the name of the notifier it belongs to. The prefix is
# stripped before the notifier sees it, so `gotify_token` arrives as `token`.
notifiers.register(
    "gotify",
    gotify_url="https://gotify.example.com",
    gotify_token="your-application-token",
    gotify_default_priority=5,
)
notifiers.register("null")

notifiers.notify(title="Deploy", message="finished")
```

Every core holds its own registry, so two cores in one process do not see each other's
notifiers. Registering a name no notifier answers to logs a warning and registers
nothing.

## Notifiers

Discovery is by filename: every `*_notifier.py` in the package is available under the
name in front of `_notifier`.

### gotify

Posts to a Gotify server's `/message` endpoint.

| **Parameter**              | **Mandatory** | **Default**       | **Description**                            |
|:---------------------------|:-------------:|:------------------|:-------------------------------------------|
| `gotify_url`               | yes           | -                 | base URL of the Gotify server              |
| `gotify_token`             | yes           | -                 | application token, kept out of the logs    |
| `gotify_content_type`      | no            | `text/markdown`   | content type of the message body           |
| `gotify_default_priority`  | no            | `0`               | priority for messages that carry none      |

`send()` accepts `title`, `message`, `priority` and `content_type`. A field that is not
given is left out of the request, and `content_type` overrides the default for that one
message. A priority that will not convert to an integer is logged and the message is
sent without one.

### null

Logs the notification at info level and reports success. Useful for a dry run.

## Writing a notifier

Add a `<name>_notifier.py` to the package with a `Notifier` subclass, a `params`
declaration and a module-level `start`:

```python
from typing import Any, ClassVar

from .notifier import Notifier


class WebhookNotifier(Notifier):
    """Posts a notification to a webhook."""

    params: ClassVar[dict[str, dict[str, Any]]] = {
        "url": {"mandatory": True, "type": "string"},
        "secret": {"mandatory": True, "redact": True, "type": "string"},
        "timeout": {"default": 10, "type": "integer"},
    }

    def send(self, **kwargs: Any) -> bool:
        """Sends the notification and reports whether it was accepted."""
        ...


start = WebhookNotifier.start
```

Each parameter declares a `type` of `boolean`, `integer` or `string`, and optionally
`mandatory`, `default` and `redact`. The base class resolves them into `self.settings`:

- a mandatory parameter has to be present, and a supplied `0`, `False` or `""` counts as
  present
- an optional parameter falls back to its `default`, or to `None` where it declares none
- a value of the wrong declared type is rejected, and an integer parameter rejects a
  boolean
- a parameter marked `redact` has its value masked out of anything the notifier logs
  through `self.redact()`

## Logging

Every module logs to the `ix-notifiers` logger and attaches no handler of its own, so
the application decides where the records go.

## Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md). Every change has to pass `ruff check`,
`ruff format --check`, `pylint` and the test suite at 100% statement and branch
coverage.

