pythonkuma 0.0.0rc0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
pythonkuma/__init__.py ADDED
@@ -0,0 +1,21 @@
1
+ """Python API wrapper for Uptime Kuma."""
2
+
3
+ from .exceptions import (
4
+ UptimeKumaAuthenticationException,
5
+ UptimeKumaConnectionException,
6
+ UptimeKumaException,
7
+ )
8
+ from .models import MonitorType, UptimeKumaApiResponse, UptimeKumaMonitor
9
+ from .uptimekuma import UptimeKuma
10
+
11
+ __version__ = "0.0.0rc0"
12
+
13
+ __all__ = [
14
+ "MonitorType",
15
+ "UptimeKuma",
16
+ "UptimeKumaApiResponse",
17
+ "UptimeKumaAuthenticationException",
18
+ "UptimeKumaConnectionException",
19
+ "UptimeKumaException",
20
+ "UptimeKumaMonitor",
21
+ ]
pythonkuma/const.py ADDED
@@ -0,0 +1,5 @@
1
+ """Uptime Kuma constants."""
2
+
3
+ from logging import Logger, getLogger
4
+
5
+ LOGGER: Logger = getLogger(__package__)
@@ -0,0 +1,71 @@
1
+ """Decorator for Uptime Kuma"""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import TYPE_CHECKING
6
+
7
+ import aiohttp
8
+
9
+ from . import exceptions
10
+ from .const import LOGGER
11
+ from .models import UptimeKumaApiResponse
12
+
13
+ if TYPE_CHECKING:
14
+ from .uptimekuma import UptimeKuma
15
+
16
+
17
+ def api_request(api_path: str, method: str = "GET"):
18
+ """Decorator for Uptime Kuma API request"""
19
+
20
+ def decorator(func):
21
+ """Decorator"""
22
+
23
+ async def wrapper(*args, **kwargs):
24
+ """Wrapper"""
25
+ client: UptimeKuma = args[0]
26
+ url = f"{client._base_url}{api_path}"
27
+ LOGGER.debug("Requesting %s", url)
28
+ try:
29
+ request = await client._session.request(
30
+ method=method,
31
+ url=url,
32
+ timeout=aiohttp.ClientTimeout(total=10),
33
+ auth=aiohttp.BasicAuth(client._username, client._password),
34
+ )
35
+
36
+ if request.status != 200:
37
+ raise exceptions.UptimeKumaConnectionException(
38
+ f"Request for '{url}' failed with status code '{request.status}'"
39
+ )
40
+
41
+ result = await request.text()
42
+ except aiohttp.ClientError as exception:
43
+ raise exceptions.UptimeKumaConnectionException(
44
+ f"Request exception for '{url}' with - {exception}"
45
+ ) from exception
46
+
47
+ except TimeoutError:
48
+ raise exceptions.UptimeKumaConnectionException(f"Request timeout for '{url}'") from None
49
+
50
+ except exceptions.UptimeKumaConnectionException as exception:
51
+ raise exceptions.UptimeKumaConnectionException(exception) from exception
52
+
53
+ except exceptions.UptimeKumaException as exception:
54
+ raise exceptions.UptimeKumaException(exception) from exception
55
+
56
+ except (Exception, BaseException) as exception:
57
+ raise exceptions.UptimeKumaException(
58
+ f"Unexpected exception for '{url}' with - {exception}"
59
+ ) from exception
60
+
61
+ LOGGER.debug("Requesting %s returned %s", url, result)
62
+
63
+ response = UptimeKumaApiResponse.from_prometheus(
64
+ {"monitors": result, "_api_path": api_path, "_method": method}
65
+ )
66
+
67
+ return response
68
+
69
+ return wrapper
70
+
71
+ return decorator
@@ -0,0 +1,13 @@
1
+ """Uptime Kuma exceptions."""
2
+
3
+
4
+ class UptimeKumaException(Exception):
5
+ """Base Uptime Kuma exception."""
6
+
7
+
8
+ class UptimeKumaConnectionException(UptimeKumaException):
9
+ """Uptime Kuma connection exception."""
10
+
11
+
12
+ class UptimeKumaAuthenticationException(UptimeKumaException):
13
+ """Uptime Kuma authentication exception."""
pythonkuma/models.py ADDED
@@ -0,0 +1,101 @@
1
+ """Uptime Kuma models"""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import dataclass
6
+ from enum import StrEnum
7
+ from typing import Any
8
+
9
+ from prometheus_client.parser import text_string_to_metric_families as parser
10
+
11
+
12
+ class MonitorType(StrEnum):
13
+ """Monitors type."""
14
+
15
+ HTTP = "http"
16
+ PORT = "port"
17
+ PING = "ping"
18
+ KEYWORD = "keyword"
19
+ DNS = "dns"
20
+ PUSH = "push"
21
+ STEAM = "steam"
22
+ MQTT = "mqtt"
23
+ SQL = "sqlserver"
24
+ JSON_QUERY = "json-query"
25
+ GROUP = "group"
26
+ DOCKER = "docker"
27
+ GRPC_KEYWORD = "grpc-keyword"
28
+ REAL_BROWSER = "real-browser"
29
+ GAMEDIG = "gamedig"
30
+ KAFKA_PRODUCER = "kafka-producer"
31
+ POSTGRES = "postgres"
32
+ MYSQL = "mysql"
33
+ MONGODB = "mongodb"
34
+ RADIUS = "radius"
35
+ REDIS = "redis"
36
+ TAILSCALE_PING = "tailscale-ping"
37
+
38
+
39
+ class UptimeKumaBaseModel:
40
+ """UptimeKumaBaseModel."""
41
+
42
+
43
+ @dataclass
44
+ class UptimeKumaMonitor(UptimeKumaBaseModel):
45
+ """Monitor model for Uptime Kuma."""
46
+
47
+ monitor_cert_days_remaining: float = 0
48
+ monitor_cert_is_valid: float = 0
49
+ monitor_hostname: str = ""
50
+ monitor_name: str = ""
51
+ monitor_port: str = ""
52
+ monitor_response_time: float = 0
53
+ monitor_status: float = 0
54
+ monitor_type: MonitorType = MonitorType.HTTP
55
+ monitor_url: str = ""
56
+
57
+ @staticmethod
58
+ def from_dict(data: dict[str, Any]) -> UptimeKumaMonitor:
59
+ """Generate object from json."""
60
+ obj: dict[str, Any] = {}
61
+ for key, value in data.items():
62
+ if hasattr(UptimeKumaMonitor, key):
63
+ obj[key] = MonitorType(value) if key == "monitor_type" else value
64
+
65
+ return UptimeKumaMonitor(**obj)
66
+
67
+
68
+ @dataclass
69
+ class UptimeKumaApiResponse(UptimeKumaBaseModel):
70
+ """API response model for Uptime Kuma."""
71
+
72
+ _method: str | None = None
73
+ _api_path: str | None = None
74
+ data: list[UptimeKumaMonitor] | None = None
75
+
76
+ @staticmethod
77
+ def from_prometheus(data: dict[str, Any]) -> UptimeKumaApiResponse:
78
+ """Generate object from json."""
79
+ obj: dict[str, Any] = {}
80
+ monitors = []
81
+
82
+ for key, value in data.items():
83
+ if hasattr(UptimeKumaApiResponse, key):
84
+ obj[key] = value
85
+
86
+ parsed = parser(data["monitors"])
87
+ for family in parsed:
88
+ for sample in family.samples:
89
+ if sample.name.startswith("monitor"):
90
+ existed = next(
91
+ (i for i, x in enumerate(monitors) if x["monitor_name"] == sample.labels["monitor_name"]),
92
+ None,
93
+ )
94
+ if existed is None:
95
+ temp = {**sample.labels, sample.name: sample.value}
96
+ monitors.append(temp)
97
+ else:
98
+ monitors[existed][sample.name] = sample.value
99
+ obj["data"] = [UptimeKumaMonitor.from_dict(monitor) for monitor in monitors]
100
+
101
+ return UptimeKumaApiResponse(**obj)
pythonkuma/py.typed ADDED
File without changes
@@ -0,0 +1,22 @@
1
+ """Uptime Kuma client."""
2
+
3
+ from aiohttp import ClientSession
4
+
5
+ from .decorator import api_request
6
+ from .models import UptimeKumaApiResponse
7
+
8
+
9
+ class UptimeKuma:
10
+ """This class is used to get information from Uptime Kuma."""
11
+
12
+ def __init__(self, session: ClientSession, base_url: str, username: str, password: str) -> None:
13
+ """Initialize"""
14
+ self.monitors = []
15
+ self._base_url = base_url
16
+ self._username = username
17
+ self._password = password
18
+ self._session: ClientSession = session
19
+
20
+ @api_request("/metrics")
21
+ async def async_get_monitors(self, **kwargs) -> UptimeKumaApiResponse:
22
+ """Get monitors from API."""
@@ -0,0 +1,55 @@
1
+ Metadata-Version: 2.4
2
+ Name: pythonkuma
3
+ Version: 0.0.0rc0
4
+ Summary: Simple Python wrapper for Uptime Kuma
5
+ Project-URL: Source, https://github.com/tr4nt0r/pythonkuma
6
+ Author-email: Manfred Dennerlein Rodelo <manfred@dennerlein.name>, Jayakorn Karikan <jayakornk@gmail.com>
7
+ License-Expression: MIT
8
+ License-File: LICENSE
9
+ Classifier: Operating System :: OS Independent
10
+ Classifier: Programming Language :: Python :: 3
11
+ Requires-Python: >=3.12
12
+ Requires-Dist: aiohttp>=3.12.9
13
+ Requires-Dist: prometheus-client>=0.21.0
14
+ Provides-Extra: dev
15
+ Requires-Dist: ruff==0.11.13; extra == 'dev'
16
+ Description-Content-Type: text/markdown
17
+
18
+ # pythonkuma
19
+ Simple Python wrapper for Uptime Kuma
20
+
21
+ ## Installation
22
+
23
+ ```shell
24
+ pip install pythonkuma
25
+ ```
26
+
27
+ ## Example
28
+
29
+ ```python
30
+ import asyncio
31
+
32
+ import aiohttp
33
+
34
+ from pythonkuma import UptimeKuma
35
+
36
+ URL = ""
37
+ USERNAME = ""
38
+ PASSWORD = ""
39
+
40
+
41
+ async def main():
42
+
43
+ async with aiohttp.ClientSession() as session:
44
+ uptime_kuma = UptimeKuma(session, URL, USERNAME, PASSWORD)
45
+ response = await uptime_kuma.async_get_monitors()
46
+ print(response.data)
47
+
48
+
49
+ asyncio.run(main())
50
+
51
+ ```
52
+
53
+ ## Credit
54
+
55
+ This library is a fork of **pyuptimekuma** by [@jayakornk](https://github.com/jayakornk)
@@ -0,0 +1,11 @@
1
+ pythonkuma/__init__.py,sha256=0g8HQqh6PFspLse23R_CV3M9isVg-kp2rzyY6W6bpdA,516
2
+ pythonkuma/const.py,sha256=eZNgS3ZW7DlaUlzDZLBuSzYBNbzmjdYliSkHgzYdq0k,109
3
+ pythonkuma/decorator.py,sha256=RcHTTT_nGTtgSiQfqdfhOF8r1cVXT2_nGgWLW9MXlbY,2390
4
+ pythonkuma/exceptions.py,sha256=zFybA27px1nXrzMLwJ_43LARDeUrzoS9ijPgZ5BC6dQ,324
5
+ pythonkuma/models.py,sha256=ihDAUGSTwUKxzu2HpQsa30Pj_jIPuP6G9Bo6c5rRjyY,2932
6
+ pythonkuma/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
+ pythonkuma/uptimekuma.py,sha256=jvcrVhBHgBbOhxKu9WUcS3aRyoQZ_LicLCf43YJB0wU,670
8
+ pythonkuma-0.0.0rc0.dist-info/METADATA,sha256=nkyH-jd1GVqOJ_mICMKZEtQJ9m_n4hasJN68HUMSr5I,1198
9
+ pythonkuma-0.0.0rc0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
10
+ pythonkuma-0.0.0rc0.dist-info/licenses/LICENSE,sha256=vpte5KMpKqofPZEJ0ltfh3-I4GhbRruAkk93GBhK-JA,1062
11
+ pythonkuma-0.0.0rc0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.27.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2022 Bacon
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.