Skip to content
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
.vscode
dist
*.egg-info
*.egg-info
__pycache__
venv
.tox
tox.ini
96 changes: 96 additions & 0 deletions gotify_message/gotify_connector.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import logging
import requests
import json

LOG = logging.getLogger(__name__)


class GotifyConnector:
URL = None
TOKEN = None

def __init__(
self,
url: str = None,
token: str = None
):

self.url = (url or self.URL)
self.token = (token or self.TOKEN)
self._check_status()

def _get(self, resource, timeout: int = None) -> dict:
headers = {"X-Gotify-Key": self.token}
url = self.url + resource
response = requests.get(url, headers=headers, timeout=timeout)

if response.ok:
return response.json()
else:
error = (
f"'{url}' response error:\n" +
json.dumps(response.json(), indent=3)
)
LOG.error(error)
return None

def _post(
self,
resource: dict = None,
payload: dict = None,
headers: dict = None,
) -> dict:

_headers = {
"X-Gotify-Key": self.token,
"Content-type": "application/json"
}
if headers:
_headers |= headers
url = self.url + resource
response = requests.post(url, headers=_headers, json=payload)

if response.ok:
return response.json()
else:
error = (
f"'{url}' response error:\n" +
json.dumps(response.json(), indent=3)
)
LOG.error(error)
return None

@property
def health(self) -> str:
response = self._get("/health", timeout=10)
status = response.get("health")
return status

@property
def database(self) -> str:
response = self._get("/health", timeout=10)
status = response.get("database")
return status

def _check_status(self):
if self.health != "green":
log_msg = (
f"Gotify service {self.url} health probblem: {self.health}"
)
LOG.warning(log_msg)
else:
log_msg = (
f"Gotify service {self.url} health status: {self.health}"
)
LOG.debug(log_msg)

if self.database != "green":
log_msg = (
f"Gotify service {self.url} database probblem: {self.database}"
)
LOG.warning(log_msg)
else:
log_msg = (
f"Gotify service {self.url} database status: {self.database}"
)
LOG.debug(log_msg)
48 changes: 21 additions & 27 deletions gotify_message/gotify_notification.py
Original file line number Diff line number Diff line change
@@ -1,39 +1,35 @@
import requests
import json
from .gotify_connector import GotifyConnector


class GotifyNotification:
class GotifyNotification(GotifyConnector):
"""Basic gotify notification class

:param url: gotify server url
:type url: str
:param app_token: token to which application send a message
:type app_token: str
:param token: token to which application send a message
:type token: str
:param title: title of the message
:type title: str
:param message: message
:type message: str
:param priority: message priority, defaults to 5
:type priority: int, optional
"""

CONTENT_TYPE = 'plain'

def __init__(
self,
url,
app_token: str,
url: str = None,
token: str = None,
title: str = None,
message: str = None,
priority: int = 5
):
"""Constructor method"""

self.url = url + '/message'
self.headers = {
"X-Gotify-Key": app_token,
"Content-type": 'application/json'
}
super().__init__(url, token)

self.payload = {
"title": title,
"priority": priority,
Expand All @@ -46,20 +42,22 @@ def __init__(
}
self.delivered = False

def send(self,
message: str = None,
title: str = None,
priority: int = None) -> requests.models.Response:
def send(
self,
message: str = None,
title: str = None,
priority: int = None
) -> bool:
"""sends message to gotify server

:param title: title of the message
:type title: str
:param message: message
:type message: str
:param title: title of the message
:type title: str
:param priority: message priority, defaults to 5
:type priority: int, optional
:return: _description_
:rtype: response.Request
:return: True is message delivered
:rtype: bool
"""

if message:
Expand All @@ -69,14 +67,10 @@ def send(self,
if priority:
self.payload['priority'] = priority

response = requests.post(
self.url,
headers=self.headers,
json=self.payload
)
if response.ok:
if self._post("/message", self.payload):
self.delivered = True
return response

return self.delivered

@property
def json(self) -> str:
Expand Down
103 changes: 103 additions & 0 deletions tests/pytest1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import unittest
import pytest
from unittest import mock
from gotify_message.gotify_connector import requests
from gotify_message.gotify_connector import GotifyConnector

URL = "http://10.0.0.7:8090"
TOKEN = "tokenASDASDA"


@pytest.fixture
def url():
return URL

@pytest.fixture
def token():
return TOKEN

@pytest.fixture
def health_response():
return {'health': 'green', 'database': 'green'}

def mock_response(fail = None):
def request(method, **kwargs):
response = requests.Response()
request = requests.Request(method)
response.status_code = 200
for attr in kwargs:
if hasattr(request, attr):
setattr(request, attr, kwargs[attr])
response.request = request
if fail:
response._content = b'{"health":"red","database":"red"}'
else:
response._content = b'{"health":"green","database":"green"}'
return response
return request


@pytest.fixture
def gotify_connector(url, token, health_response):
with mock.patch("requests.get", new=mock.MagicMock()):
requests.get().json.return_value = health_response
requests.get().ok = True
yield GotifyConnector(url, token)

@pytest.fixture
def gotify_connector_mock_response(url, token):
with mock.patch("requests.get", new=mock_response()):
yield GotifyConnector(url, token)

@pytest.fixture
def gotify_connector_mock_response_fail(url, token):
with mock.patch("requests.get", side_effect=mock_response(fail=True)):
yield GotifyConnector(url, token)

class TestConnector:

def test_constructor(self, gotify_connector):
assert gotify_connector.url == "http://10.0.0.7:8090"
assert gotify_connector.token == "tokenASDASDA"
assert gotify_connector.health == "green"
assert gotify_connector.database == "green"

def test_constructor_2(self):
with mock.patch("requests.get"):
requests.get().json.return_value = {'health': 'green', 'database': 'green'}
requests.get().ok = True
gotify_connector = GotifyConnector("http://10.0.0.7:8090","tokenASDASDA")
assert gotify_connector.url == "http://10.0.0.7:8090"
assert gotify_connector.token == "tokenASDASDA"
assert gotify_connector.health == "green"
assert gotify_connector.database == "green"

def test_constructor_3(self):
with mock.patch("requests.get"):
requests.get.side_effect = requests.exceptions.HTTPError
with pytest.raises(requests.exceptions.HTTPError):
gotify_connector = GotifyConnector("http://10.0.0.7:8090","tokenASDASDA")


def test_constructor_mock_response(self, gotify_connector_mock_response):
assert gotify_connector_mock_response.url == "http://10.0.0.7:8090"
assert gotify_connector_mock_response.token == "tokenASDASDA"
assert gotify_connector_mock_response.health == "green"
assert gotify_connector_mock_response.database == "green"

def test_constructor_mock_response_fail(self, gotify_connector_mock_response_fail):
assert gotify_connector_mock_response_fail.url == "http://10.0.0.7:8090"
assert gotify_connector_mock_response_fail.token == "tokenASDASDA"
assert gotify_connector_mock_response_fail.health == "red"
assert gotify_connector_mock_response_fail.database == "red"

@mock.patch("requests.get", side_effect=mock_response(fail=True))
def test_constructor_1(self, m__get):
client = GotifyConnector("http://10.0.0.7:8090", "daskjdsakjn")
assert client.url == "http://10.0.0.7:8090"
assert client.token == "daskjdsakjn"
assert client.health == "red"
assert client.database == "red"



44 changes: 44 additions & 0 deletions tests/test_connector.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
from pytest import fixture,raises
from mock import patch
from gotify_message.gotify_connector import requests
from gotify_message.gotify_connector import GotifyConnector


URL="http://1.2.3.4:8888"
TOKEN="lskd12314sadf1"




@fixture
@patch("requests.get")
def gotify_connector2(m__get):
m__get().json.return_value = {'health': 'green', 'database': 'green'}
m__get().ok = True
yield GotifyConnector(URL, TOKEN)


def mock_get(**kwargs):
request = requests.Request(**kwargs)
response = requests.Response()
response.status_code = 200
response._content = {'health': 'green', 'database': 'green'}
return request

@fixture
def gotify_connector():
with patch("requests.get"):
requests.get().json.return_value = {'health': 'green', 'database': 'green'}
requests.get().ok= True
yield GotifyConnector(URL, TOKEN)

def test_connector(gotify_connector):
assert gotify_connector.health == "green"
assert gotify_connector.database == "green"


def test_1():
with patch("requests.get", new=mock_get):
requests.get(method="GET")


Loading