1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229
|
Metadata-Version: 2.1
Name: pywebpush
Version: 2.0.3
Summary: WebPush publication library
Author-email: JR Conlin <src+webpusher@jrconlin.com>
License: MPL-2.0
Project-URL: Homepage, https://github.com/web-push-libs/pywebpush
Keywords: webpush,vapid,notification
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: aiohttp
Requires-Dist: cryptography>=2.6.1
Requires-Dist: http-ece>=1.1.0
Requires-Dist: requests>=2.21.0
Requires-Dist: six>=1.15.0
Requires-Dist: py-vapid>=1.7.0
Provides-Extra: dev
Requires-Dist: black; extra == "dev"
Requires-Dist: mock; extra == "dev"
Requires-Dist: pytest; extra == "dev"
# Webpush Data encryption library for Python
[](https://travis-ci.org/web-push-libs/pywebpush)
[](https://requires.io/github/web-push-libs/pywebpush/requirements/?branch=main)
This library is available on [pypi as pywebpush](https://pypi.python.org/pypi/pywebpush).
Source is available on [github](https://github.com/mozilla-services/pywebpush).
Please note: This library was designated as a `Critical Project` by PyPi, it is currently
maintained by [a single person](https://xkcd.com/2347/). I still accept PRs and Issues, but
make of that what you will.
## Installation
To work with this repo locally, you'll need to run `python -m venv venv`.
Then `venv/bin/pip install --editable .`
## Usage
In the browser, the promise handler for
[registration.pushManager.subscribe()](https://developer.mozilla.org/en-US/docs/Web/API/PushManager/subscribe)
returns a
[PushSubscription](https://developer.mozilla.org/en-US/docs/Web/API/PushSubscription)
object. This object has a .toJSON() method that will return a JSON object that contains all the info we need to encrypt
and push data.
As illustration, a `subscription_info` object may look like:
```json
{
"endpoint": "https://updates.push.services.mozilla.com/push/v1/gAA...",
"keys": { "auth": "k8J...", "p256dh": "BOr..." }
}
```
How you send the PushSubscription data to your backend, store it
referenced to the user who requested it, and recall it when there's
a new push subscription update is left as an exercise for the
reader.
### Sending Data using `webpush()` One Call
In many cases, your code will be sending a single message to many
recipients. There's a "One Call" function which will make things
easier.
```python
from pywebpush import webpush
webpush(subscription_info,
data,
vapid_private_key="Private Key or File Path[1]",
vapid_claims={"sub": "mailto:YourEmailAddress"})
```
This will encode `data`, add the appropriate VAPID auth headers if required and send it to the push server identified
in the `subscription_info` block.
##### Parameters
_subscription_info_ - The `dict` of the subscription info (described above).
_data_ - can be any serial content (string, bit array, serialized JSON, etc), but be sure that your receiving
application is able to parse and understand it. (e.g. `data = "Mary had a little lamb."`)
_content_type_ - specifies the form of Encryption to use, either `'aes128gcm'` or the deprecated `'aesgcm'`. NOTE that
not all User Agents can decrypt `'aesgcm'`, so the library defaults to the RFC 8188 standard form.
_vapid_claims_ - a `dict` containing the VAPID claims required for authorization (See
[py_vapid](https://github.com/web-push-libs/vapid/tree/master/python) for more details). If `aud` is not specified,
pywebpush will attempt to auto-fill from the `endpoint`. If `exp` is not specified or set in the past, it will be set
to 12 hours from now. In both cases, the passed `dict` **will be mutated** after the call.
_vapid_private_key_ - Either a path to a VAPID EC2 private key PEM file, or a string containing the DER representation.
(See [py_vapid](https://github.com/web-push-libs/vapid/tree/master/python) for more details.) The `private_key` may be
a base64 encoded DER formatted private key, or the path to an OpenSSL exported private key file.
e.g. the output of:
```bash
openssl ecparam -name prime256v1 -genkey -noout -out private_key.pem
```
##### Example
```python
from pywebpush import webpush, WebPushException
try:
webpush(
subscription_info={
"endpoint": "https://push.example.com/v1/12345",
"keys": {
"p256dh": "0123abcde...",
"auth": "abc123..."
}},
data="Mary had a little lamb, with a nice mint jelly",
vapid_private_key="path/to/vapid_private.pem",
vapid_claims={
"sub": "mailto:YourNameHere@example.org",
}
)
except WebPushException as ex:
print("I'm sorry, Dave, but I can't do that: {}", repr(ex))
# Mozilla returns additional information in the body of the response.
if ex.response is not None and ex.response.json():
extra = ex.response.json()
print("Remote service replied with a {}:{}, {}",
extra.code,
extra.errno,
extra.message
)
```
### Methods
If you expect to resend to the same recipient, or have more needs than just sending data quickly, you
can pass just `wp = WebPusher(subscription_info)`. This will return a `WebPusher` object.
The following methods are available:
#### `.send(data, headers={}, ttl=0, gcm_key="", reg_id="", content_encoding="aes128gcm", curl=False, timeout=None)`
Send the data using additional parameters. On error, returns a `WebPushException`
##### Parameters
_data_ Binary string of data to send
_headers_ A `dict` containing any additional headers to send
_ttl_ Message Time To Live on Push Server waiting for the client to reconnect (in seconds)
_gcm_key_ Google Cloud Messaging key (if using the older GCM push system) This is the API key obtained from the Google
Developer Console.
_reg_id_ Google Cloud Messaging registration ID (will be extracted from endpoint if not specified)
_content_encoding_ ECE content encoding type (defaults to "aes128gcm")
_curl_ Do not execute the POST, but return as a `curl` command. This will write the encrypted content to a local file
named `encrpypted.data`. This command is meant to be used for debugging purposes.
_timeout_ timeout for requests POST query.
See [requests documentation](http://docs.python-requests.org/en/master/user/quickstart/#timeouts).
##### Example
to send from Chrome using the old GCM mode:
```python
WebPusher(subscription_info).send(data, headers, ttl, gcm_key)
```
#### `.encode(data, content_encoding="aes128gcm")`
Encode the `data` for future use. On error, returns a `WebPushException`
##### Parameters
_data_ Binary string of data to send
_content_encoding_ ECE content encoding type (defaults to "aes128gcm")
*Note* This will return a `NoData` exception if the data is not present or empty. It is completely
valid to send a WebPush notification with no data, but encoding is a no-op in that case. Best not
to call it if you don't have data.
##### Example
```python
encoded_data = WebPush(subscription_info).encode(data)
```
## Stand Alone Webpush
If you're not really into coding your own solution, there's also a "stand-alone" `pywebpush` command in the
./bin directory.
This uses two files:
- the _data_ file, which contains the message to send, in whatever form you like.
- the _subscription info_ file, which contains the subscription information as JSON encoded data. This is usually returned by the Push `subscribe` method and looks something like:
```json
{
"endpoint": "https://push...",
"keys": {
"auth": "ab01...",
"p256dh": "aa02..."
}
}
```
If you're interested in just testing your applications WebPush interface, you could use the Command Line:
```bash
./bin/pywebpush --data stuff_to_send.data --info subscription.info
```
which will encrypt and send the contents of `stuff_to_send.data`.
See `./bin/pywebpush --help` for available commands and options.
|