pywebpush 2.4.0__tar.gz → 2.5.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.
- {pywebpush-2.4.0 → pywebpush-2.5.0}/CHANGELOG.md +5 -0
- {pywebpush-2.4.0 → pywebpush-2.5.0}/PKG-INFO +6 -1
- {pywebpush-2.4.0 → pywebpush-2.5.0}/README.md +5 -0
- {pywebpush-2.4.0 → pywebpush-2.5.0}/README.rst +5 -5
- {pywebpush-2.4.0 → pywebpush-2.5.0}/pyproject.toml +1 -1
- {pywebpush-2.4.0 → pywebpush-2.5.0}/pywebpush/__init__.py +25 -1
- {pywebpush-2.4.0 → pywebpush-2.5.0}/pywebpush/tests/test_webpush.py +13 -0
- {pywebpush-2.4.0 → pywebpush-2.5.0}/pywebpush.egg-info/PKG-INFO +6 -1
- {pywebpush-2.4.0 → pywebpush-2.5.0}/CODE_OF_CONDUCT.md +0 -0
- {pywebpush-2.4.0 → pywebpush-2.5.0}/LICENSE +0 -0
- {pywebpush-2.4.0 → pywebpush-2.5.0}/MANIFEST.in +0 -0
- {pywebpush-2.4.0 → pywebpush-2.5.0}/entry_points.txt +0 -0
- {pywebpush-2.4.0 → pywebpush-2.5.0}/pywebpush/__main__.py +0 -0
- {pywebpush-2.4.0 → pywebpush-2.5.0}/pywebpush/tests/__init__.py +0 -0
- {pywebpush-2.4.0 → pywebpush-2.5.0}/pywebpush.egg-info/SOURCES.txt +0 -0
- {pywebpush-2.4.0 → pywebpush-2.5.0}/pywebpush.egg-info/dependency_links.txt +0 -0
- {pywebpush-2.4.0 → pywebpush-2.5.0}/pywebpush.egg-info/entry_points.txt +0 -0
- {pywebpush-2.4.0 → pywebpush-2.5.0}/pywebpush.egg-info/requires.txt +0 -0
- {pywebpush-2.4.0 → pywebpush-2.5.0}/pywebpush.egg-info/top_level.txt +0 -0
- {pywebpush-2.4.0 → pywebpush-2.5.0}/requirements.txt +0 -0
- {pywebpush-2.4.0 → pywebpush-2.5.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pywebpush
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.5.0
|
|
4
4
|
Summary: WebPush publication library
|
|
5
5
|
Author-email: JR Conlin <src+webpusher@jrconlin.com>
|
|
6
6
|
License-Expression: MPL-2.0
|
|
@@ -132,6 +132,11 @@ try:
|
|
|
132
132
|
)
|
|
133
133
|
except WebPushException as ex:
|
|
134
134
|
print("I'm sorry, Dave, but I can't do that: {}", repr(ex))
|
|
135
|
+
# status_code works with both webpush() and webpush_async().
|
|
136
|
+
if ex.status_code in (429, 503):
|
|
137
|
+
print("Push service requested a retry after:", ex.retry_after)
|
|
138
|
+
# retry_after is either a delay in seconds or an HTTP date:
|
|
139
|
+
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Retry-After
|
|
135
140
|
# Mozilla returns additional information in the body of the response.
|
|
136
141
|
if ex.response is not None and ex.response.json():
|
|
137
142
|
extra = ex.response.json()
|
|
@@ -104,6 +104,11 @@ try:
|
|
|
104
104
|
)
|
|
105
105
|
except WebPushException as ex:
|
|
106
106
|
print("I'm sorry, Dave, but I can't do that: {}", repr(ex))
|
|
107
|
+
# status_code works with both webpush() and webpush_async().
|
|
108
|
+
if ex.status_code in (429, 503):
|
|
109
|
+
print("Push service requested a retry after:", ex.retry_after)
|
|
110
|
+
# retry_after is either a delay in seconds or an HTTP date:
|
|
111
|
+
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Retry-After
|
|
107
112
|
# Mozilla returns additional information in the body of the response.
|
|
108
113
|
if ex.response is not None and ex.response.json():
|
|
109
114
|
extra = ex.response.json()
|
|
@@ -219,11 +219,11 @@ If you’re not really into coding your own solution, there’s also a
|
|
|
219
219
|
|
|
220
220
|
This uses two files:
|
|
221
221
|
|
|
222
|
-
-
|
|
223
|
-
|
|
224
|
-
-
|
|
225
|
-
|
|
226
|
-
|
|
222
|
+
- the *data* file, which contains the message to send, in whatever form
|
|
223
|
+
you like.
|
|
224
|
+
- the *subscription info* file, which contains the subscription
|
|
225
|
+
information as JSON encoded data. This is usually returned by the
|
|
226
|
+
Push ``subscribe`` method and looks something like:
|
|
227
227
|
|
|
228
228
|
.. code:: json
|
|
229
229
|
|
|
@@ -25,7 +25,11 @@ from requests import Response
|
|
|
25
25
|
class WebPushException(Exception):
|
|
26
26
|
"""Web Push failure.
|
|
27
27
|
|
|
28
|
-
This may contain
|
|
28
|
+
This may contain a requests.Response or aiohttp.ClientResponse.
|
|
29
|
+
|
|
30
|
+
``status_code`` and ``retry_after`` provide a common interface for
|
|
31
|
+
inspecting either response type without discarding the original
|
|
32
|
+
``response`` object.
|
|
29
33
|
|
|
30
34
|
"""
|
|
31
35
|
|
|
@@ -44,6 +48,26 @@ class WebPushException(Exception):
|
|
|
44
48
|
extra = f", Response {self.response}"
|
|
45
49
|
return f"WebPushException: {self.message}{extra}"
|
|
46
50
|
|
|
51
|
+
@property
|
|
52
|
+
def status_code(self) -> int | None:
|
|
53
|
+
"""Return the HTTP status for synchronous or asynchronous responses."""
|
|
54
|
+
if self.response is None:
|
|
55
|
+
return None
|
|
56
|
+
return getattr(
|
|
57
|
+
self.response,
|
|
58
|
+
"status_code",
|
|
59
|
+
getattr(self.response, "status", None),
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
@property
|
|
63
|
+
def retry_after(self) -> str | None:
|
|
64
|
+
"""Return the provider's Retry-After header, when present.
|
|
65
|
+
|
|
66
|
+
The value can be either a delay in seconds or an HTTP date. See
|
|
67
|
+
https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Retry-After
|
|
68
|
+
"""
|
|
69
|
+
return getattr(self.response, "headers", {}).get("Retry-After", None)
|
|
70
|
+
|
|
47
71
|
|
|
48
72
|
class NoData(Exception):
|
|
49
73
|
"""Message contained No Data, no encoding required."""
|
|
@@ -563,6 +563,8 @@ class WebpushExceptionTestCase(unittest.TestCase):
|
|
|
563
563
|
|
|
564
564
|
exp = WebPushException("foo")
|
|
565
565
|
assert f"{exp}" == "WebPushException: foo"
|
|
566
|
+
assert exp.status_code is None
|
|
567
|
+
assert exp.retry_after is None
|
|
566
568
|
# Really should try to load the response to verify, but this mock
|
|
567
569
|
# covers what we need.
|
|
568
570
|
response = Mock(spec=Response)
|
|
@@ -577,9 +579,20 @@ class WebpushExceptionTestCase(unittest.TestCase):
|
|
|
577
579
|
response.json.return_value = json.loads(response.text)
|
|
578
580
|
response.status_code = 401
|
|
579
581
|
response.reason = "Unauthorized"
|
|
582
|
+
response.headers = {"Retry-After": "120"}
|
|
580
583
|
exp = WebPushException("foo", response)
|
|
581
584
|
assert f"{exp}" == "WebPushException: foo, Response {}".format(response.text)
|
|
582
585
|
assert f"{exp.response}", "<Response [401]>"
|
|
583
586
|
assert cast(requests.Response, exp.response).json().get("errno") == 109
|
|
587
|
+
assert exp.status_code == 401
|
|
588
|
+
assert exp.retry_after == "120"
|
|
589
|
+
|
|
590
|
+
async_response = Mock(spec=["status", "headers", "text"])
|
|
591
|
+
async_response.status = 503
|
|
592
|
+
async_response.headers = {"Retry-After": "Wed, 21 Oct 2015 07:28:00 GMT"}
|
|
593
|
+
exp = WebPushException("async failure", async_response)
|
|
594
|
+
assert exp.status_code == 503
|
|
595
|
+
assert exp.retry_after == "Wed, 21 Oct 2015 07:28:00 GMT"
|
|
596
|
+
|
|
584
597
|
exp = WebPushException("foo", [1, 2, 3])
|
|
585
598
|
assert f"{exp}" == "WebPushException: foo, Response [1, 2, 3]"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pywebpush
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.5.0
|
|
4
4
|
Summary: WebPush publication library
|
|
5
5
|
Author-email: JR Conlin <src+webpusher@jrconlin.com>
|
|
6
6
|
License-Expression: MPL-2.0
|
|
@@ -132,6 +132,11 @@ try:
|
|
|
132
132
|
)
|
|
133
133
|
except WebPushException as ex:
|
|
134
134
|
print("I'm sorry, Dave, but I can't do that: {}", repr(ex))
|
|
135
|
+
# status_code works with both webpush() and webpush_async().
|
|
136
|
+
if ex.status_code in (429, 503):
|
|
137
|
+
print("Push service requested a retry after:", ex.retry_after)
|
|
138
|
+
# retry_after is either a delay in seconds or an HTTP date:
|
|
139
|
+
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Retry-After
|
|
135
140
|
# Mozilla returns additional information in the body of the response.
|
|
136
141
|
if ex.response is not None and ex.response.json():
|
|
137
142
|
extra = ex.response.json()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|