python-ntfy 0.2.3__tar.gz → 0.2.4__tar.gz

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: python-ntfy
3
- Version: 0.2.3
3
+ Version: 0.2.4
4
4
  Summary: An ntfy library aiming for feature completeness
5
5
  Home-page: https://github.com/MatthewCane/python-ntfy
6
6
  License: MIT
@@ -14,6 +14,7 @@ Classifier: Programming Language :: Python :: 3
14
14
  Classifier: Programming Language :: Python :: 3.11
15
15
  Classifier: Programming Language :: Python :: 3.12
16
16
  Classifier: Programming Language :: Python :: 3.13
17
+ Requires-Dist: mypy (>=1.12.0,<2.0.0)
17
18
  Requires-Dist: requests (>=2.31.0,<3.0.0)
18
19
  Project-URL: Documentation, https://matthewcane.github.io/python-ntfy/
19
20
  Project-URL: Repository, https://github.com/MatthewCane/python-ntfy
@@ -62,21 +63,25 @@ See the full documentation site at [https://matthewcane.github.io/python-ntfy/](
62
63
  - Email notifications
63
64
  - Send to multiple topics at once
64
65
 
65
- ## Test and Development
66
+ ## Testing and Development
66
67
 
67
68
  This project uses:
68
69
 
69
70
  - Poetry as it's dependency manager
70
71
  - Ruff for linting and code formatting
72
+ - MyPy for static type checking
71
73
 
72
74
  To install dev dependencies, run `poetry install --with dev`.
73
75
 
74
- ### Linting and Formatting
76
+ ### Linting, Formatting and Type Checking
75
77
 
76
78
  These can be run with:
77
79
 
78
80
  - `poetry run ruff format`
79
81
  - `poetry run ruff check`
82
+ - `poetry run mypy .`
83
+
84
+ These tools are also run in the CI pipeline and must pass before merging.
80
85
 
81
86
  ### Tests
82
87
 
@@ -87,11 +92,11 @@ You can run the tests against a local instance of `ntfy` *or* `ntfy.sh`.
87
92
  #### Setup Steps
88
93
 
89
94
  1. To test against a *local* `ntfy` instance:
90
- i. Create a container using `docker run -p 80:80 -it binwiederhier/ntfy serve --attachment-cache-dir=/cache --base-url=http://localhost`
91
- ii. Set the following key in the `.env` file: `NTFY_SERVER=http://localhost`
92
- iii. Add a dummy username and password to `.env` (see example.env)
93
- 2. To test against https://ntfy.sh:
94
- i. Add username and password for ntfy.sh to `.env` (see example.env)
95
+ i. Create a container using `docker run -p 80:80 -it binwiederhier/ntfy serve --attachment-cache-dir=/cache --base-url=http://localhost`
96
+ ii. Set the following key in the `.env` file: `NTFY_SERVER=http://localhost`
97
+ iii. Add a dummy username and password to `.env` (see example.env)
98
+ 2. To test against `https://ntfy.sh`:
99
+ i. Add username and password for ntfy.sh to `.env` (see example.env)
95
100
  3. Run the tests with `poetry run pytest --cov`
96
101
 
97
102
  The tests will sent messages to the `python_ntfy_testing` topic so you will need to subcribe to that topic to see the test messages.
@@ -41,21 +41,25 @@ See the full documentation site at [https://matthewcane.github.io/python-ntfy/](
41
41
  - Email notifications
42
42
  - Send to multiple topics at once
43
43
 
44
- ## Test and Development
44
+ ## Testing and Development
45
45
 
46
46
  This project uses:
47
47
 
48
48
  - Poetry as it's dependency manager
49
49
  - Ruff for linting and code formatting
50
+ - MyPy for static type checking
50
51
 
51
52
  To install dev dependencies, run `poetry install --with dev`.
52
53
 
53
- ### Linting and Formatting
54
+ ### Linting, Formatting and Type Checking
54
55
 
55
56
  These can be run with:
56
57
 
57
58
  - `poetry run ruff format`
58
59
  - `poetry run ruff check`
60
+ - `poetry run mypy .`
61
+
62
+ These tools are also run in the CI pipeline and must pass before merging.
59
63
 
60
64
  ### Tests
61
65
 
@@ -66,11 +70,11 @@ You can run the tests against a local instance of `ntfy` *or* `ntfy.sh`.
66
70
  #### Setup Steps
67
71
 
68
72
  1. To test against a *local* `ntfy` instance:
69
- i. Create a container using `docker run -p 80:80 -it binwiederhier/ntfy serve --attachment-cache-dir=/cache --base-url=http://localhost`
70
- ii. Set the following key in the `.env` file: `NTFY_SERVER=http://localhost`
71
- iii. Add a dummy username and password to `.env` (see example.env)
72
- 2. To test against https://ntfy.sh:
73
- i. Add username and password for ntfy.sh to `.env` (see example.env)
73
+ i. Create a container using `docker run -p 80:80 -it binwiederhier/ntfy serve --attachment-cache-dir=/cache --base-url=http://localhost`
74
+ ii. Set the following key in the `.env` file: `NTFY_SERVER=http://localhost`
75
+ iii. Add a dummy username and password to `.env` (see example.env)
76
+ 2. To test against `https://ntfy.sh`:
77
+ i. Add username and password for ntfy.sh to `.env` (see example.env)
74
78
  3. Run the tests with `poetry run pytest --cov`
75
79
 
76
80
  The tests will sent messages to the `python_ntfy_testing` topic so you will need to subcribe to that topic to see the test messages.
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "python-ntfy"
3
- version = "0.2.3"
3
+ version = "0.2.4"
4
4
  description = "An ntfy library aiming for feature completeness"
5
5
  authors = ["Matthew Cane <matthew.cane0@gmail.com>"]
6
6
  readme = "README.md"
@@ -15,6 +15,7 @@ classifiers = [
15
15
  [tool.poetry.dependencies]
16
16
  python = "^3.11"
17
17
  requests = "^2.31.0"
18
+ mypy = "^1.12.0"
18
19
 
19
20
  [tool.poetry.group.dev.dependencies]
20
21
  pytest = ">=7.4.1,<9.0.0"
@@ -24,6 +25,10 @@ pytest-codecov = ">=0.5.1,<0.7.0"
24
25
  ruff = "^0.7.0"
25
26
  mkdocs-material = "^9.5.41"
26
27
  mkdocstrings-python = "^1.12.1"
28
+ types-pygments = "^2.18.0.20240506"
29
+ types-colorama = "^0.4.15.20240311"
30
+ types-requests = "^2.32.0.20241016"
31
+ types-setuptools = "^75.2.0.20241018"
27
32
 
28
33
  [build-system]
29
34
  requires = ["poetry-core"]
@@ -1,27 +1,38 @@
1
1
  import os
2
+ from types import MethodType
3
+ from ._send_functions import (
4
+ send,
5
+ send_file,
6
+ MessagePriority,
7
+ ViewAction,
8
+ BroadcastAction,
9
+ HttpAction,
10
+ )
11
+ from ._get_functions import get_cached_messages
2
12
 
3
13
 
4
14
  class NtfyClient:
5
- from ._send_functions import (
6
- send,
7
- send_file,
8
- MessagePriority,
9
- ViewAction,
10
- BroadcastAction,
11
- HttpAction,
12
- )
13
- from ._get_functions import get_cached_messages
14
-
15
15
  def __init__(
16
16
  self,
17
17
  topic: str,
18
18
  server: str = "https://ntfy.sh",
19
- ):
19
+ ) -> None:
20
20
  """
21
21
  :param topic: The topic to use for this client
22
22
  :param server: The server to connect to. Must include the protocol (http/https)
23
- :return:
23
+ :return None:
24
24
  """
25
+ # Bind the imported functions to the class
26
+ self.send = MethodType(send, self)
27
+ self.send_file = MethodType(send_file, self)
28
+ self.MessagePriority = MethodType(MessagePriority, self)
29
+ self.get_cached_messages = MethodType(get_cached_messages, self)
30
+
31
+ # These are Enums that don't need to be bound
32
+ self.ViewAction = ViewAction
33
+ self.BroadcastAction = BroadcastAction
34
+ self.HttpAction = HttpAction
35
+
25
36
  self._server = os.environ.get("NTFY_SERVER") or server
26
37
  self._topic = topic
27
38
  self.__set_url(self._server, topic)
@@ -45,3 +56,11 @@ class NtfyClient:
45
56
  """
46
57
  self._topic = topic
47
58
  self.__set_url(self._server, self._topic)
59
+
60
+ def get_topic(self):
61
+ """
62
+ Get the current topic
63
+
64
+ :return: str
65
+ """
66
+ return self._topic
@@ -21,7 +21,7 @@ def get_cached_messages(
21
21
 
22
22
  params = {"poll": "1"}
23
23
  if scheduled:
24
- params.update({"scheduled": scheduled})
24
+ params.update({"scheduled": str(scheduled)})
25
25
  if since:
26
26
  params.update({"since": since})
27
27
 
@@ -63,7 +63,7 @@ class BroadcastAction(Action):
63
63
  self.action = ActionType.BROADCAST
64
64
  self.intent = intent
65
65
  self.extras = extras
66
- super().__init__(label, ActionType.BROADCAST, clear)
66
+ super().__init__(label, ActionType.BROADCAST.value, clear)
67
67
 
68
68
  def to_dict(self) -> dict:
69
69
  return {
@@ -87,7 +87,7 @@ class HttpAction(Action):
87
87
  label: str,
88
88
  url: str,
89
89
  method: str = "POST",
90
- headers: Optional[dict] = None,
90
+ headers: Optional[dict[str, str]] = None,
91
91
  body: Optional[str] = None,
92
92
  clear: bool = False,
93
93
  ):
@@ -97,8 +97,8 @@ class HttpAction(Action):
97
97
  self.body = body
98
98
  super().__init__(label, url, clear)
99
99
 
100
- def to_dict(self) -> dict:
101
- action_dict = {
100
+ def to_dict(self) -> dict[str, Union[str, bool, dict[str, str]]]:
101
+ action_dict: dict[str, Union[str, bool, dict[str, str]]] = {
102
102
  "action": self.action.value,
103
103
  "label": self.label,
104
104
  "url": self.url,
@@ -127,10 +127,10 @@ class HttpAction(Action):
127
127
  def send(
128
128
  self,
129
129
  message: str,
130
- title: str = None,
131
- priority: Optional[MessagePriority] = MessagePriority.DEFAULT,
130
+ title: Optional[str] = None,
131
+ priority: MessagePriority = MessagePriority.DEFAULT,
132
132
  tags: list = [],
133
- actions: list[Union[ViewAction, BroadcastAction, HttpAction, None]] = [],
133
+ actions: list[Union[ViewAction, BroadcastAction, HttpAction]] = [],
134
134
  format_as_markdown: bool = False,
135
135
  ) -> dict:
136
136
  """
@@ -167,10 +167,10 @@ def send(
167
167
  def send_file(
168
168
  self,
169
169
  file: str,
170
- title: str = None,
171
- priority: Optional[MessagePriority] = MessagePriority.DEFAULT,
170
+ title: Optional[str] = None,
171
+ priority: MessagePriority = MessagePriority.DEFAULT,
172
172
  tags: list = [],
173
- actions: list[Union[ViewAction, BroadcastAction, HttpAction, None]] = [],
173
+ actions: list[Union[ViewAction, BroadcastAction, HttpAction]] = [],
174
174
  ) -> dict:
175
175
  """
176
176
  Send a file to the server
@@ -186,17 +186,15 @@ def send_file(
186
186
  response = client.send_file(file_path="example.txt")
187
187
  """
188
188
  headers = {
189
- "Title": title,
189
+ "Title": str(title),
190
190
  "Filename": file.split("/")[-1],
191
191
  "Priority": priority.value,
192
192
  "Tags": ",".join(tags),
193
193
  "Actions": " ; ".join([action.to_header() for action in actions]),
194
194
  }
195
195
 
196
- with open(file, "rb") as file:
196
+ with open(file, "rb") as f:
197
197
  response = json.loads(
198
- requests.post(
199
- url=self.url, data=file, headers=headers, auth=self._auth
200
- ).text
198
+ requests.post(url=self.url, data=f, headers=headers, auth=self._auth).text
201
199
  )
202
200
  return response
File without changes