python-ntfy 0.5.2__tar.gz → 0.6.1__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.3
2
2
  Name: python-ntfy
3
- Version: 0.5.2
3
+ Version: 0.6.1
4
4
  Summary: An ntfy library aiming for feature completeness
5
5
  License: MIT
6
6
  Author: Matthew Cane
@@ -28,11 +28,7 @@ An easy-to-use python library for the [ntfy notification service](https://ntfy.s
28
28
  ## Quickstart
29
29
 
30
30
  1. Install using pip with `pip3 install python-ntfy`
31
- 2. Configure the following environment variables:
32
- - `NTFY_USER`: The username for your server (if required)
33
- - `NTFY_PASSWORD`: The password for your server (if required)
34
- - `NTFY_SERVER`: The server URL (defaults to `https://ntft.sh`)
35
- 3. Setup your application to use the library:
31
+ 2. Use the `NtfyClient` to send messages:
36
32
 
37
33
  ```python
38
34
  # Import the ntfy client
@@ -45,6 +41,8 @@ client = NtfyClient(topic="Your topic")
45
41
  client.send("Your message here")
46
42
  ```
47
43
 
44
+ For information on setting up authentication, see the [quickstart guide](https://matthewcane.github.io/python-ntfy/quickstart/).
45
+
48
46
  ## Documentation
49
47
 
50
48
  See the full documentation at [https://matthewcane.github.io/python-ntfy/](https://matthewcane.github.io/python-ntfy/).
@@ -61,11 +59,7 @@ See the full documentation at [https://matthewcane.github.io/python-ntfy/](https
61
59
  - Scheduled delivery
62
60
  - Tags
63
61
  - Action buttons
64
-
65
- ## Future Features
66
-
67
- - [Email notifications](https://docs.ntfy.sh/publish/#e-mail-notifications)
68
- - Send to multiple topics at once
62
+ - Email notifications
69
63
 
70
64
  ## Contributing
71
65
 
@@ -9,11 +9,7 @@ An easy-to-use python library for the [ntfy notification service](https://ntfy.s
9
9
  ## Quickstart
10
10
 
11
11
  1. Install using pip with `pip3 install python-ntfy`
12
- 2. Configure the following environment variables:
13
- - `NTFY_USER`: The username for your server (if required)
14
- - `NTFY_PASSWORD`: The password for your server (if required)
15
- - `NTFY_SERVER`: The server URL (defaults to `https://ntft.sh`)
16
- 3. Setup your application to use the library:
12
+ 2. Use the `NtfyClient` to send messages:
17
13
 
18
14
  ```python
19
15
  # Import the ntfy client
@@ -26,6 +22,8 @@ client = NtfyClient(topic="Your topic")
26
22
  client.send("Your message here")
27
23
  ```
28
24
 
25
+ For information on setting up authentication, see the [quickstart guide](https://matthewcane.github.io/python-ntfy/quickstart/).
26
+
29
27
  ## Documentation
30
28
 
31
29
  See the full documentation at [https://matthewcane.github.io/python-ntfy/](https://matthewcane.github.io/python-ntfy/).
@@ -42,11 +40,7 @@ See the full documentation at [https://matthewcane.github.io/python-ntfy/](https
42
40
  - Scheduled delivery
43
41
  - Tags
44
42
  - Action buttons
45
-
46
- ## Future Features
47
-
48
- - [Email notifications](https://docs.ntfy.sh/publish/#e-mail-notifications)
49
- - Send to multiple topics at once
43
+ - Email notifications
50
44
 
51
45
  ## Contributing
52
46
 
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "python-ntfy"
3
- version = "0.5.2"
3
+ version = "0.6.1"
4
4
  description = "An ntfy library aiming for feature completeness"
5
5
  authors = ["Matthew Cane <matthew.cane0@gmail.com>"]
6
6
  readme = "README.md"
@@ -24,7 +24,7 @@ mkdocstrings = {extras = ["python"], version = ">=0.26.2,<0.30.0"}
24
24
  mypy = "^1.12.0"
25
25
  pytest = ">=7.4.1,<9.0.0"
26
26
  python-dotenv = "^1.0.0"
27
- pytest-asyncio = ">=0.21.1,<1.1.0"
27
+ pytest-asyncio = ">=0.21.1,<1.2.0"
28
28
  pytest-codecov = ">=0.5.1,<0.8.0"
29
29
  ruff = ">=0.7,<0.13"
30
30
  mkdocs-material = "^9.5.41"
@@ -46,12 +46,14 @@ class NtfyClient(GetFunctionsMixin, SendFunctionsMixin):
46
46
  self,
47
47
  topic: str,
48
48
  server: str = "https://ntfy.sh",
49
+ auth: tuple[str, str] | str | None = None,
49
50
  ) -> None:
50
51
  """Itinialize the NtfyClient.
51
52
 
52
53
  Args:
53
54
  topic: The topic to use for this client
54
55
  server: The server to connect to. Must include the protocol (http/https)
56
+ auth: The authentication credentials to use for this client. Takes precedence over environment variables. Can be a tuple of (user, password) or a token.
55
57
 
56
58
  Returns:
57
59
  None
@@ -65,18 +67,39 @@ class NtfyClient(GetFunctionsMixin, SendFunctionsMixin):
65
67
  self._server = os.environ.get("NTFY_SERVER") or server
66
68
  self._topic = topic
67
69
  self.__set_url(self._server, topic)
70
+ self._auth: tuple[str, str] | None = self._resolve_auth(auth)
68
71
 
69
- # If the user has set the user and password, use that
70
- # If the user has set the token, use that
71
- # Otherwise, use None
72
-
73
- self._auth: tuple[str, str] | None = None
74
- if (user := os.environ.get("NTFY_USER")) and (
75
- password := os.environ.get("NTFY_PASSWORD")
76
- ):
77
- self._auth = (user, password)
78
- elif token := os.environ.get("NTFY_TOKEN"):
79
- self._auth = ("", token)
72
+ def _resolve_auth(
73
+ self, auth: tuple[str, str] | str | None
74
+ ) -> tuple[str, str] | None:
75
+ """Resolve the authentication credentials.
76
+
77
+ Args:
78
+ auth: The authentication credentials to use for this client. Takes precedence over environment variables. Can be a tuple of (user, password) or a token string.
79
+
80
+ Returns:
81
+ tuple[str, str] | None: The authentication credentials.
82
+ """
83
+ # If the user has supplied credentials, use them (including empty string)
84
+ if auth is not None:
85
+ if isinstance(auth, tuple):
86
+ return auth
87
+ if isinstance(auth, str):
88
+ return ("", auth)
89
+
90
+ # Otherwise, check environment variables
91
+ user = os.environ.get("NTFY_USER")
92
+ password = os.environ.get("NTFY_PASSWORD")
93
+ token = os.environ.get("NTFY_TOKEN")
94
+
95
+ if user and password:
96
+ return (user, password)
97
+
98
+ if token:
99
+ return ("", token)
100
+
101
+ # If no credentials are found, return None
102
+ return None
80
103
 
81
104
  def __set_url(
82
105
  self,
@@ -192,6 +192,7 @@ def send(
192
192
  schedule: Optional[datetime] = None,
193
193
  format_as_markdown: bool = False,
194
194
  timeout_seconds: int = 5,
195
+ email: Optional[str] = None,
195
196
  ) -> dict:
196
197
  """Send a text-based message to the server.
197
198
 
@@ -208,6 +209,7 @@ def send(
208
209
  format_as_markdown: If true, the message will be formatted as markdown.
209
210
  additional_topics: A list of additional topics to send the message to.
210
211
  timeout_seconds: The number of seconds to wait before timing out the reqest to the server.
212
+ email: Forward messages to an email address. Only one email address can be specified.
211
213
 
212
214
  Returns:
213
215
  dict: The response from the server.
@@ -236,6 +238,9 @@ def send(
236
238
  if len(actions) > 0:
237
239
  headers["Actions"] = " ; ".join([action.to_header() for action in actions])
238
240
 
241
+ if email:
242
+ headers["Email"] = email
243
+
239
244
  if schedule:
240
245
  headers["Delay"] = str(int(schedule.timestamp()))
241
246
 
@@ -259,6 +264,7 @@ def send_file(
259
264
  actions: Optional[list[Union[ViewAction, BroadcastAction, HttpAction]]] = None,
260
265
  schedule: Optional[datetime] = None,
261
266
  timeout_seconds: int = 30,
267
+ email: Optional[str] = None,
262
268
  ) -> dict:
263
269
  """Sends a file to the server.
264
270
 
@@ -270,6 +276,7 @@ def send_file(
270
276
  actions: A list of ActionButton objects to attach to the message.
271
277
  schedule: The time to schedule the message to be sent. Must be more than 10 seconds away and less than 3 days in the future.
272
278
  timeout_seconds: The number of seconds to wait before timing out.
279
+ email: Forward messages to an email address. Only one email address can be specified.
273
280
 
274
281
  Returns:
275
282
  dict: The response from the server.
@@ -293,6 +300,9 @@ def send_file(
293
300
  "Actions": " ; ".join([action.to_header() for action in actions]),
294
301
  }
295
302
 
303
+ if email:
304
+ headers["Email"] = email
305
+
296
306
  if schedule:
297
307
  headers["Delay"] = str(int(schedule.timestamp()))
298
308
 
File without changes