python-ntfy 0.7.2__tar.gz → 0.8.0__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.4
2
2
  Name: python-ntfy
3
- Version: 0.7.2
3
+ Version: 0.8.0
4
4
  Summary: An ntfy library aiming for feature completeness
5
5
  Keywords: ntfy,notifications,push,http,api
6
6
  Author: Matthew Cane
@@ -18,7 +18,7 @@ Classifier: Topic :: Communications
18
18
  Classifier: Topic :: Internet :: WWW/HTTP
19
19
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
20
20
  Requires-Dist: requests>=2.31.0
21
- Requires-Dist: mkdocstrings[python]>=0.26.2,<0.30.0 ; extra == 'dev'
21
+ Requires-Dist: mkdocstrings[python]>=0.26.2,<0.31.0 ; extra == 'dev'
22
22
  Requires-Dist: mypy>=1.12.0,<2.0.0 ; extra == 'dev'
23
23
  Requires-Dist: pytest>=7.4.1,<9.0.0 ; extra == 'dev'
24
24
  Requires-Dist: python-dotenv>=1.0.0,<2.0.0 ; extra == 'dev'
@@ -86,25 +86,23 @@ See the full documentation at [https://matthewcane.github.io/python-ntfy/](https
86
86
 
87
87
  ## Contributing
88
88
 
89
- This project uses:
89
+ We welcome contributions! This project aims to provide a complete and user-friendly Python library for ntfy. Here's how you can help:
90
90
 
91
- - [uv](https://github.com/astral-sh/uv) as its dependency manager
92
- - [Just](https://github.com/casey/just) as a task runner
93
- - [Pre-commit](https://pre-commit.com/) for running checks before each commit
94
- - [Docker](https://www.docker.com/) and [Docker Compose](https://docs.docker.com/compose/) for running tests
91
+ ### Prerequisites
95
92
 
96
- These need to be installed separately to run the tasks.
93
+ Before contributing, you'll need to install these tools:
97
94
 
98
- To see all available tasks, run `just`.
95
+ - **[uv](https://github.com/astral-sh/uv)** - Fast Python package manager and installer
96
+ - **[Just](https://github.com/casey/just)** - Command runner for project tasks
97
+ - **[Docker](https://www.docker.com/)** and **[Docker Compose](https://docs.docker.com/compose/)** - For running tests with ntfy servers
98
+ - **[Pre-commit](https://pre-commit.com/)** - Git hooks for code quality (optional but recommended)
99
99
 
100
- Some useful tasks are:
100
+ ### Development Steps
101
101
 
102
- - `just install` - Install dependencies (including dev dependencies)
103
- - `just test` - Run all tests and checks
104
- - `just check` - Run code quality checks (ruff + mypy)
105
- - `just format` - Format code with ruff
106
- - `just serve-docs` - Build and serve the docs locally
102
+ - Fork the repository and make your changes
103
+ - Run `just setup` to install the pre-commit hooks
104
+ - Run `just format` to format the code
105
+ - Run `just test` to run all the tests
106
+ - Create a pull request with detailed description of your changes
107
107
 
108
- ### Tests
109
-
110
- This project is aiming for 95% code coverage. Any added features must include comprehensive tests.
108
+ Thank you for contributing to python-ntfy! 🚀
@@ -44,25 +44,23 @@ See the full documentation at [https://matthewcane.github.io/python-ntfy/](https
44
44
 
45
45
  ## Contributing
46
46
 
47
- This project uses:
47
+ We welcome contributions! This project aims to provide a complete and user-friendly Python library for ntfy. Here's how you can help:
48
48
 
49
- - [uv](https://github.com/astral-sh/uv) as its dependency manager
50
- - [Just](https://github.com/casey/just) as a task runner
51
- - [Pre-commit](https://pre-commit.com/) for running checks before each commit
52
- - [Docker](https://www.docker.com/) and [Docker Compose](https://docs.docker.com/compose/) for running tests
49
+ ### Prerequisites
53
50
 
54
- These need to be installed separately to run the tasks.
51
+ Before contributing, you'll need to install these tools:
55
52
 
56
- To see all available tasks, run `just`.
53
+ - **[uv](https://github.com/astral-sh/uv)** - Fast Python package manager and installer
54
+ - **[Just](https://github.com/casey/just)** - Command runner for project tasks
55
+ - **[Docker](https://www.docker.com/)** and **[Docker Compose](https://docs.docker.com/compose/)** - For running tests with ntfy servers
56
+ - **[Pre-commit](https://pre-commit.com/)** - Git hooks for code quality (optional but recommended)
57
57
 
58
- Some useful tasks are:
58
+ ### Development Steps
59
59
 
60
- - `just install` - Install dependencies (including dev dependencies)
61
- - `just test` - Run all tests and checks
62
- - `just check` - Run code quality checks (ruff + mypy)
63
- - `just format` - Format code with ruff
64
- - `just serve-docs` - Build and serve the docs locally
60
+ - Fork the repository and make your changes
61
+ - Run `just setup` to install the pre-commit hooks
62
+ - Run `just format` to format the code
63
+ - Run `just test` to run all the tests
64
+ - Create a pull request with detailed description of your changes
65
65
 
66
- ### Tests
67
-
68
- This project is aiming for 95% code coverage. Any added features must include comprehensive tests.
66
+ Thank you for contributing to python-ntfy! 🚀
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "python-ntfy"
3
- version = "0.7.2"
3
+ version = "0.8.0"
4
4
  description = "An ntfy library aiming for feature completeness"
5
5
  readme = "README.md"
6
6
  license = "MIT"
@@ -20,9 +20,7 @@ classifiers = [
20
20
  "Topic :: Software Development :: Libraries :: Python Modules",
21
21
  ]
22
22
  keywords = ["ntfy", "notifications", "push", "http", "api"]
23
- authors = [
24
- {name = "Matthew Cane", email = "matthew.cane0@gmail.com"}
25
- ]
23
+ authors = [{ name = "Matthew Cane", email = "matthew.cane0@gmail.com" }]
26
24
 
27
25
  [project.urls]
28
26
  Homepage = "https://github.com/matthewcane/python-ntfy"
@@ -41,36 +39,36 @@ module-root = ""
41
39
 
42
40
  [tool.uv]
43
41
  dev-dependencies = [
44
- "mkdocstrings[python]>=0.26.2,<0.30.0",
42
+ "mkdocstrings[python]>=0.26.2,<0.31.0",
45
43
  "mypy>=1.12.0,<2.0.0",
46
44
  "pytest>=7.4.1,<9.0.0",
47
45
  "python-dotenv>=1.0.0,<2.0.0",
48
46
  "pytest-asyncio>=0.21.1,<1.2.0",
49
- "pytest-codecov>=0.5.1,<0.8.0",
47
+ "pytest-codecov>=0.5.1,<0.8.0",
50
48
  "ruff>=0.7,<0.13",
51
49
  "mkdocs-material>=9.5.41,<10.0.0",
52
50
  "mkdocstrings-python>=1.12.1,<2.0.0",
53
51
  "types-pygments>=2.18.0.20240506",
54
52
  "types-colorama>=0.4.15.20240311",
55
53
  "types-requests>=2.32.0.20241016",
56
- "types-setuptools>=75.2.0.20241018,<81.0.0.0"
54
+ "types-setuptools>=75.2.0.20241018,<81.0.0.0",
57
55
  ]
58
56
 
59
57
  [project.optional-dependencies]
60
58
  dev = [
61
- "mkdocstrings[python]>=0.26.2,<0.30.0",
59
+ "mkdocstrings[python]>=0.26.2,<0.31.0",
62
60
  "mypy>=1.12.0,<2.0.0",
63
61
  "pytest>=7.4.1,<9.0.0",
64
62
  "python-dotenv>=1.0.0,<2.0.0",
65
63
  "pytest-asyncio>=0.21.1,<1.2.0",
66
- "pytest-codecov>=0.5.1,<0.8.0",
64
+ "pytest-codecov>=0.5.1,<0.8.0",
67
65
  "ruff>=0.7,<0.13",
68
66
  "mkdocs-material>=9.5.41,<10.0.0",
69
67
  "mkdocstrings-python>=1.12.1,<2.0.0",
70
68
  "types-pygments>=2.18.0.20240506",
71
69
  "types-colorama>=0.4.15.20240311",
72
70
  "types-requests>=2.32.0.20241016",
73
- "types-setuptools>=75.2.0.20241018,<81.0.0.0"
71
+ "types-setuptools>=75.2.0.20241018,<81.0.0.0",
74
72
  ]
75
73
 
76
74
  [tool.ruff]
@@ -0,0 +1,11 @@
1
+ class MessageSendError(Exception):
2
+ """Exception raised when a message fails to send."""
3
+
4
+ def __init__(self, message: str) -> None:
5
+ """Initialize the exception.
6
+
7
+ Args:
8
+ message: The message to display.
9
+ """
10
+ self.message = message
11
+ super().__init__(self.message)
@@ -59,7 +59,7 @@ class NtfyClient(GetFunctionsMixin, SendFunctionsMixin):
59
59
  None
60
60
 
61
61
  Exceptions:
62
- ToDo
62
+ None
63
63
 
64
64
  Examples:
65
65
  client = NtfyClient(topic="my_topic")
@@ -1,10 +1,11 @@
1
- import json
2
1
  from datetime import datetime
3
2
  from enum import Enum
4
3
  from pathlib import Path
5
4
 
6
5
  import requests
7
6
 
7
+ from python_ntfy._exceptions import MessageSendError
8
+
8
9
 
9
10
  class MessagePriority(Enum):
10
11
  """Ntfy message priority levels.
@@ -214,7 +215,7 @@ def send(
214
215
  dict: The response from the server.
215
216
 
216
217
  Raises:
217
- ToDo
218
+ MessageSendError: If the message fails to send.
218
219
 
219
220
  Examples:
220
221
  >>> response = client.send(message="Example message")
@@ -243,20 +244,24 @@ def send(
243
244
  if schedule:
244
245
  headers["Delay"] = str(int(schedule.timestamp()))
245
246
 
246
- return json.loads(
247
- requests.post(
247
+ try:
248
+ response = requests.post(
248
249
  url=self.url,
249
250
  data=message,
250
251
  headers=headers,
251
252
  auth=self._auth,
252
253
  timeout=timeout_seconds,
253
- ).text,
254
- )
254
+ )
255
+ response.raise_for_status()
256
+ return response.json()
257
+ except requests.exceptions.RequestException as e:
258
+ error_message = f"Failed to send message: {e}"
259
+ raise MessageSendError(error_message) from e
255
260
 
256
261
 
257
262
  def send_file(
258
263
  self,
259
- file: str,
264
+ file: str | Path,
260
265
  title: str | None = None,
261
266
  priority: MessagePriority = MessagePriority.DEFAULT,
262
267
  tags: list | None = None,
@@ -268,7 +273,7 @@ def send_file(
268
273
  """Sends a file to the server.
269
274
 
270
275
  Args:
271
- file: The path to the file to send.
276
+ file: The file to send.
272
277
  title: The title of the file.
273
278
  priority: The priority of the message. Optional, defaults to MessagePriority.
274
279
  tags: A list of tags to attach to the message. Can be an emoji short code.
@@ -281,7 +286,7 @@ def send_file(
281
286
  dict: The response from the server.
282
287
 
283
288
  Raises:
284
- ToDo
289
+ MessageSendError: If the message fails to send.
285
290
 
286
291
  Examples:
287
292
  >>> response = client.send_file(file="example.txt")
@@ -291,9 +296,17 @@ def send_file(
291
296
  if tags is None:
292
297
  tags = []
293
298
 
299
+ try:
300
+ data = Path(file).read_bytes()
301
+ except Exception as e:
302
+ error_message = f"Failed to read file: {e}"
303
+ raise MessageSendError(error_message) from e
304
+
305
+ filename = Path(file).name
306
+
294
307
  headers = {
295
308
  "Title": str(title),
296
- "Filename": file.split("/")[-1],
309
+ "Filename": filename,
297
310
  "Priority": priority.value,
298
311
  "Tags": ",".join(tags),
299
312
  "Actions": " ; ".join([action.to_header() for action in actions]),
@@ -305,13 +318,16 @@ def send_file(
305
318
  if schedule:
306
319
  headers["Delay"] = str(int(schedule.timestamp()))
307
320
 
308
- with Path(file).open("rb") as f:
309
- return json.loads(
310
- requests.post(
311
- url=self.url,
312
- data=f,
313
- headers=headers,
314
- auth=self._auth,
315
- timeout=timeout_seconds,
316
- ).text,
321
+ try:
322
+ response = requests.post(
323
+ url=self.url,
324
+ data=data,
325
+ headers=headers,
326
+ auth=self._auth,
327
+ timeout=timeout_seconds,
317
328
  )
329
+ response.raise_for_status()
330
+ return response.json()
331
+ except requests.exceptions.RequestException as e:
332
+ error_message = f"Failed to send file: {e}"
333
+ raise MessageSendError(error_message) from e