python-ntfy 0.2.0__tar.gz → 0.2.2__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.
@@ -0,0 +1,89 @@
1
+ Metadata-Version: 2.1
2
+ Name: python-ntfy
3
+ Version: 0.2.2
4
+ Summary: An ntfy library aiming for feature completeness
5
+ Author: Matthew Cane
6
+ Author-email: matthew.cane0@gmail.com
7
+ Requires-Python: >=3.11,<4.0
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Programming Language :: Python :: 3.11
10
+ Classifier: Programming Language :: Python :: 3.12
11
+ Classifier: Programming Language :: Python :: 3.13
12
+ Requires-Dist: requests (>=2.31.0,<3.0.0)
13
+ Description-Content-Type: text/markdown
14
+
15
+ # A Python Library For ntfy.sh
16
+
17
+ An easy-to-use ntfy python library. Aiming for full feature support.
18
+
19
+ ## Quickstart
20
+
21
+ 1. Install using pip with `pip3 install python-ntfy`
22
+ 2. Configure the following environment variables:
23
+ - `NTFY_USER`: The username for your server (if required)
24
+ - `NTFY_PASSWORD`: The password for your server (if required)
25
+ - `NTFY_SERVER`: The server URL (defaults to https://ntft.sh)
26
+ 3. Setup your application to use the library:
27
+
28
+ ```python
29
+ # Import the ntfy client
30
+ from python_ntfy import NtfyClient
31
+
32
+ # Create an `NtfyClient` instance with a topic
33
+ client = NtfyClient(topic="Your topic")
34
+
35
+ # Send a message
36
+ client.send("Your message here")
37
+ ```
38
+
39
+ ## Supported Features
40
+
41
+ - Username + password auth
42
+ - Custom servers
43
+ - Sending plaintext messages
44
+ - Sending Markdown formatted text messages
45
+ - Retrieving cached messages
46
+ - Scheduled delivery
47
+
48
+ ## Future Features
49
+
50
+ - Access token auth
51
+ - Email notifications
52
+ - Tags
53
+ - Action buttons
54
+ - Send to multiple topics at once
55
+
56
+ ## Test and Development
57
+
58
+ This project uses:
59
+
60
+ - Poetry as it's dependency manager
61
+ - Ruff for linting and code formatting
62
+
63
+ To install dev dependencies, run `poetry install --with dev`.
64
+
65
+ ### Linting and Formatting
66
+
67
+ These can be run with:
68
+
69
+ - `poetry run ruff format`
70
+ - `poetry run ruff check`
71
+
72
+ ### Tests
73
+
74
+ This project is aiming for 95% code coverage. Any added features must include comprihensive tests.
75
+
76
+ You can run the tests against a local instance of `ntfy` *or* `ntfy.sh`.
77
+
78
+ #### Setup Steps
79
+
80
+ 1. To test against a *local* `ntfy` instance:
81
+ i. Create a container using `docker run -p 80:80 -it binwiederhier/ntfy serve --attachment-cache-dir=/cache --base-url=http://localhost`
82
+ ii. Set the following key in the `.env` file: `NTFY_SERVER=http://localhost`
83
+ iii. Add a dummy username and password to `.env` (see example.env)
84
+ 2. To test against https://ntfy.sh:
85
+ i. Add username and password for ntfy.sh to `.env` (see example.env)
86
+ 3. Run the tests with `poetry run pytest --cov`
87
+
88
+ 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.
89
+
@@ -0,0 +1,74 @@
1
+ # A Python Library For ntfy.sh
2
+
3
+ An easy-to-use ntfy python library. Aiming for full feature support.
4
+
5
+ ## Quickstart
6
+
7
+ 1. Install using pip with `pip3 install python-ntfy`
8
+ 2. Configure the following environment variables:
9
+ - `NTFY_USER`: The username for your server (if required)
10
+ - `NTFY_PASSWORD`: The password for your server (if required)
11
+ - `NTFY_SERVER`: The server URL (defaults to https://ntft.sh)
12
+ 3. Setup your application to use the library:
13
+
14
+ ```python
15
+ # Import the ntfy client
16
+ from python_ntfy import NtfyClient
17
+
18
+ # Create an `NtfyClient` instance with a topic
19
+ client = NtfyClient(topic="Your topic")
20
+
21
+ # Send a message
22
+ client.send("Your message here")
23
+ ```
24
+
25
+ ## Supported Features
26
+
27
+ - Username + password auth
28
+ - Custom servers
29
+ - Sending plaintext messages
30
+ - Sending Markdown formatted text messages
31
+ - Retrieving cached messages
32
+ - Scheduled delivery
33
+
34
+ ## Future Features
35
+
36
+ - Access token auth
37
+ - Email notifications
38
+ - Tags
39
+ - Action buttons
40
+ - Send to multiple topics at once
41
+
42
+ ## Test and Development
43
+
44
+ This project uses:
45
+
46
+ - Poetry as it's dependency manager
47
+ - Ruff for linting and code formatting
48
+
49
+ To install dev dependencies, run `poetry install --with dev`.
50
+
51
+ ### Linting and Formatting
52
+
53
+ These can be run with:
54
+
55
+ - `poetry run ruff format`
56
+ - `poetry run ruff check`
57
+
58
+ ### Tests
59
+
60
+ This project is aiming for 95% code coverage. Any added features must include comprihensive tests.
61
+
62
+ You can run the tests against a local instance of `ntfy` *or* `ntfy.sh`.
63
+
64
+ #### Setup Steps
65
+
66
+ 1. To test against a *local* `ntfy` instance:
67
+ i. Create a container using `docker run -p 80:80 -it binwiederhier/ntfy serve --attachment-cache-dir=/cache --base-url=http://localhost`
68
+ ii. Set the following key in the `.env` file: `NTFY_SERVER=http://localhost`
69
+ iii. Add a dummy username and password to `.env` (see example.env)
70
+ 2. To test against https://ntfy.sh:
71
+ i. Add username and password for ntfy.sh to `.env` (see example.env)
72
+ 3. Run the tests with `poetry run pytest --cov`
73
+
74
+ 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.0"
3
+ version = "0.2.2"
4
4
  description = "An ntfy library aiming for feature completeness"
5
5
  authors = ["Matthew Cane <matthew.cane0@gmail.com>"]
6
6
  readme = "README.md"
@@ -9,11 +9,12 @@ readme = "README.md"
9
9
  python = "^3.11"
10
10
  requests = "^2.31.0"
11
11
 
12
- [tool.poetry.group.test.dependencies]
13
- pytest = "^7.4.1"
12
+ [tool.poetry.group.dev.dependencies]
13
+ pytest = ">=7.4.1,<9.0.0"
14
14
  python-dotenv = "^1.0.0"
15
- pytest-asyncio = "^0.21.1"
16
- pytest-codecov = "^0.5.1"
15
+ pytest-asyncio = ">=0.21.1,<0.25.0"
16
+ pytest-codecov = ">=0.5.1,<0.7.0"
17
+ ruff = "^0.7.0"
17
18
 
18
19
  [build-system]
19
20
  requires = ["poetry-core"]
@@ -1,7 +1,15 @@
1
1
  import os
2
2
 
3
+
3
4
  class NtfyClient:
4
- from ._send_functions import send, send_file, MessagePriority, ViewAction, BroadcastAction, HttpAction
5
+ from ._send_functions import (
6
+ send,
7
+ send_file,
8
+ MessagePriority,
9
+ ViewAction,
10
+ BroadcastAction,
11
+ HttpAction,
12
+ )
5
13
  from ._get_functions import get_cached_messages
6
14
 
7
15
  def __init__(
@@ -1,4 +1,5 @@
1
- import json, requests
1
+ import json
2
+ import requests
2
3
 
3
4
 
4
5
  def get_cached_messages(self, since: str = "all", scheduled: bool = False):
@@ -1,33 +1,39 @@
1
- import json, requests
1
+ import json
2
+ import requests
2
3
  from enum import Enum
3
4
  from typing import Optional, Union
4
5
 
6
+
5
7
  class MessagePriority(Enum):
6
8
  """
7
9
  Ntfy message priority levels.
8
10
  """
11
+
9
12
  MIN = "1"
10
13
  LOW = "2"
11
14
  DEFAULT = "3"
12
15
  HIGH = "4"
13
16
  MAX = "5"
14
17
  URGENT = MAX
15
-
18
+
19
+
16
20
  class ActionType(Enum):
17
21
  """
18
22
  Action button types
19
23
  """
24
+
20
25
  VIEW = "view"
21
26
  BROADCAST = "broadcast"
22
27
  HTTP = "http"
23
28
 
24
- class Action():
29
+
30
+ class Action:
25
31
  def __init__(self, label: str, url: str, clear: bool = False):
26
32
  self.label = label
27
33
  self.url = url
28
34
  self.actions: list = []
29
35
  self.clear = clear
30
-
36
+
31
37
 
32
38
  class ViewAction(Action):
33
39
  def __init__(self, label: str, url: str, clear: bool = False):
@@ -39,14 +45,21 @@ class ViewAction(Action):
39
45
  "action": self.action.value,
40
46
  "label": self.label,
41
47
  "url": self.url,
42
- "clear": self.clear
48
+ "clear": self.clear,
43
49
  }
44
-
50
+
45
51
  def to_header(self):
46
52
  return f"action={self.action.value}, label={self.label}, url={self.url}, clear={self.clear}"
47
53
 
54
+
48
55
  class BroadcastAction(Action):
49
- def __init__(self, label: str, intent: str = "io.heckel.ntfy.USER_ACTION", extras: Optional[dict] = None, clear: bool = False):
56
+ def __init__(
57
+ self,
58
+ label: str,
59
+ intent: str = "io.heckel.ntfy.USER_ACTION",
60
+ extras: Optional[dict] = None,
61
+ clear: bool = False,
62
+ ):
50
63
  self.action = ActionType.BROADCAST
51
64
  self.intent = intent
52
65
  self.extras = extras
@@ -57,26 +70,27 @@ class BroadcastAction(Action):
57
70
  "action": self.action.value,
58
71
  "label": self.label,
59
72
  "extras": self.extras,
60
- "clear": self.clear
73
+ "clear": self.clear,
61
74
  }
62
-
75
+
63
76
  def to_header(self):
64
77
  extras = ""
65
78
  if self.extras is not None:
66
79
  for key, value in self.extras.items():
67
80
  extras += f"{key}={value},"
68
81
  return f"action={self.action.value}, label={self.label}, url={self.url}, clear={self.clear}"
69
-
82
+
83
+
70
84
  class HttpAction(Action):
71
85
  def __init__(
72
- self,
73
- label: str,
74
- url: str,
75
- method: str = "POST",
76
- headers: Optional[dict] = None,
77
- body: Optional[str] = None,
78
- clear: bool = False
79
- ):
86
+ self,
87
+ label: str,
88
+ url: str,
89
+ method: str = "POST",
90
+ headers: Optional[dict] = None,
91
+ body: Optional[str] = None,
92
+ clear: bool = False,
93
+ ):
80
94
  self.action = ActionType.HTTP
81
95
  self.method = method
82
96
  self.headers = headers
@@ -89,14 +103,14 @@ class HttpAction(Action):
89
103
  "label": self.label,
90
104
  "url": self.url,
91
105
  "method": self.method,
92
- "clear": self.clear
106
+ "clear": self.clear,
93
107
  }
94
108
  if self.headers:
95
109
  action_dict["headers"] = self.headers
96
110
  if self.body:
97
111
  action_dict["body"] = self.body
98
112
  return action_dict
99
-
113
+
100
114
  def to_header(self):
101
115
  header_str = f"action={self.action.value}, label={self.label}, url={self.url}, method={self.method}, clear={self.clear}"
102
116
  if self.headers is not None:
@@ -111,14 +125,14 @@ class HttpAction(Action):
111
125
 
112
126
 
113
127
  def send(
114
- self,
115
- message: str,
116
- title: str = None,
117
- priority: Optional[MessagePriority] = MessagePriority.DEFAULT,
118
- tags: list = [],
119
- actions: list[Union[ViewAction, BroadcastAction, HttpAction, None]] = [],
120
- format_as_markdown: bool = False
121
- ):
128
+ self,
129
+ message: str,
130
+ title: str = None,
131
+ priority: Optional[MessagePriority] = MessagePriority.DEFAULT,
132
+ tags: list = [],
133
+ actions: list[Union[ViewAction, BroadcastAction, HttpAction, None]] = [],
134
+ format_as_markdown: bool = False,
135
+ ):
122
136
  """
123
137
  Send a text based message to the server
124
138
 
@@ -142,7 +156,7 @@ def send(
142
156
  "Markdown": "true" if format_as_markdown else "false",
143
157
  }
144
158
  if len(actions) > 0:
145
- headers['Actions'] = " ; ".join([action.to_header() for action in actions])
159
+ headers["Actions"] = " ; ".join([action.to_header() for action in actions])
146
160
 
147
161
  response = json.loads(
148
162
  requests.post(url=self.url, data=message, headers=headers, auth=self._auth).text
@@ -151,17 +165,17 @@ def send(
151
165
 
152
166
 
153
167
  def send_file(
154
- self,
155
- file: str,
156
- title: str = None,
157
- priority: Optional[MessagePriority] = MessagePriority.DEFAULT,
158
- tags: list = [],
159
- actions: list[Union[ViewAction, BroadcastAction, HttpAction, None]] = []
160
- ):
168
+ self,
169
+ file: str,
170
+ title: str = None,
171
+ priority: Optional[MessagePriority] = MessagePriority.DEFAULT,
172
+ tags: list = [],
173
+ actions: list[Union[ViewAction, BroadcastAction, HttpAction, None]] = [],
174
+ ):
161
175
  """
162
176
  Send a file to the server
163
177
 
164
- :param file_path: The path to the file to send.
178
+ :param file_path: The path to the file to send.
165
179
  :param title: The title of the file. Optional
166
180
  :param priority: The priority of the message. Optional, defaults to MessagePriority.DEFAULT
167
181
  :param tags: A list of tags to attach to the message. Can be an emoji short code. Optional
@@ -172,12 +186,12 @@ def send_file(
172
186
  response = client.send_file(file_path="example.txt")
173
187
  """
174
188
  headers = {
175
- "Title": title,
189
+ "Title": title,
176
190
  "Filename": file.split("/")[-1],
177
191
  "Priority": priority.value,
178
192
  "Tags": ",".join(tags),
179
- "Actions": " ; ".join([action.to_header() for action in actions])
180
- }
193
+ "Actions": " ; ".join([action.to_header() for action in actions]),
194
+ }
181
195
 
182
196
  with open(file, "rb") as file:
183
197
  response = json.loads(
@@ -1,71 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: python-ntfy
3
- Version: 0.2.0
4
- Summary: An ntfy library aiming for feature completeness
5
- Author: Matthew Cane
6
- Author-email: matthew.cane0@gmail.com
7
- Requires-Python: >=3.11,<4.0
8
- Classifier: Programming Language :: Python :: 3
9
- Classifier: Programming Language :: Python :: 3.11
10
- Classifier: Programming Language :: Python :: 3.12
11
- Classifier: Programming Language :: Python :: 3.13
12
- Requires-Dist: requests (>=2.31.0,<3.0.0)
13
- Description-Content-Type: text/markdown
14
-
15
- # ntfy.sh Python Library
16
-
17
- An easy-to-use ntfy python library. Aiming for full feature support.
18
-
19
- ## Quickstart
20
-
21
- 1. Install using pip with `pip3 install python-ntfy`
22
- 2. If you are using a server that requires auth, set the env vars
23
- 3. Import the library
24
-
25
- ```python
26
- from python_ntfy import NtfyClient
27
- ```
28
-
29
- 4. Create an `NtfyClient` instance with a topic
30
-
31
- ```python
32
- client = NtfyClient(topic="Your topic")
33
- ```
34
-
35
- 5. Send a message
36
-
37
- ```python
38
- client.send("Your message here")
39
- ```
40
-
41
- ## Supported Features
42
-
43
- - Username + password auth
44
- - Custom servers
45
- - Sending plaintext messages
46
- - Sending Markdown formatted text messages
47
- - Retrieving cached messages
48
- - Scheduled delivery
49
-
50
- ## Future Features
51
-
52
- - Access token auth
53
- - Email notifications
54
- - Tags
55
- - Action buttons
56
- - Send to multiple topics at once
57
-
58
- ## Test and Development
59
-
60
- This project uses Poetry.
61
-
62
- ### Tests
63
-
64
- This project is aiming for 95% code coverage. Any added features must include comprihensive tests.
65
-
66
- To run tests:
67
-
68
- 1. `poetry install --include test`
69
- 2. Add username and password for ntfy.sh to `.env`
70
- 3. `poetry run pytest --cov`
71
-
@@ -1,56 +0,0 @@
1
- # ntfy.sh Python Library
2
-
3
- An easy-to-use ntfy python library. Aiming for full feature support.
4
-
5
- ## Quickstart
6
-
7
- 1. Install using pip with `pip3 install python-ntfy`
8
- 2. If you are using a server that requires auth, set the env vars
9
- 3. Import the library
10
-
11
- ```python
12
- from python_ntfy import NtfyClient
13
- ```
14
-
15
- 4. Create an `NtfyClient` instance with a topic
16
-
17
- ```python
18
- client = NtfyClient(topic="Your topic")
19
- ```
20
-
21
- 5. Send a message
22
-
23
- ```python
24
- client.send("Your message here")
25
- ```
26
-
27
- ## Supported Features
28
-
29
- - Username + password auth
30
- - Custom servers
31
- - Sending plaintext messages
32
- - Sending Markdown formatted text messages
33
- - Retrieving cached messages
34
- - Scheduled delivery
35
-
36
- ## Future Features
37
-
38
- - Access token auth
39
- - Email notifications
40
- - Tags
41
- - Action buttons
42
- - Send to multiple topics at once
43
-
44
- ## Test and Development
45
-
46
- This project uses Poetry.
47
-
48
- ### Tests
49
-
50
- This project is aiming for 95% code coverage. Any added features must include comprihensive tests.
51
-
52
- To run tests:
53
-
54
- 1. `poetry install --include test`
55
- 2. Add username and password for ntfy.sh to `.env`
56
- 3. `poetry run pytest --cov`