Skip to main content

This package lets your server send Web Push Notifications to your clients. NOTE: No particular web framework are required (e.g. Django, Flask, Pyramid, etc.), since it was originally designed to run on a Raspberry Pi with no web server installed (only a bare Python program listening on a port for HTTP requests).

Project description

# Solid Web Push

This package lets your server send Web Push Notifications to your clients.
NOTE: **No** particular Web framework are required (e.g. Django, Flask, Pyramid, etc.), since
it was originally designed to run on a Raspberry Pi with no web server installed (
only a bare Python script listening on a port for HTTP requests).

---
## 1. Installation

### 1.1 Using pip

~~~
sudo pip install solidwebpush
~~~

### 1.2. Manual installation (recomended for Raspberry Pi)

1. Download this repository
2. Copy the "solidwebpush" folder (the one with the `_init_.py` in it)
3. Paste it into your project folder. NOTE: it has to be the folder in which you have the python script that will `import solidwebpush`.
4. Install the required packages; open the terminal and write:
~~~
sudo pip install ecdsa
sudo pip install python-jose
sudo pip install http_ece
sudo pip install pyelliptic
sudo pip install py-vapid
~~~
**Note:** In case of an error, specially if you're on **Raspbian**, try installing these packages before trying again (it worked for me!):
~~~
sudo apt-get install python-crypto
sudo apt-get install python-cryptography
~~~

And that's it, you're ready to go, buddy! :D

---
## 2. "Hello World" Example

In order for us to be able to send a "Hello World" notification from our server to our client devices, we should have the client-side all set up, and that's why first we need to do [this Google codelab](https://developers.google.com/web/fundamentals/getting-started/codelabs/push-notifications/) before we move forward _(Note: if you're already familiar with Web Push Notifications, you could just skip this part; otherwise, don't have to worry! it shouldn't take you too much time to get it done, trust me :D )_.

Assuming you have finished the [codelab](https://developers.google.com/web/fundamentals/getting-started/codelabs/push-notifications/), the first thing we need to do is to **generate** our own **server public key** so we can subscribe our serviceWorker(_sw.js_) in the client devices. But don't worry, _solidwebpush_ automatically does this for us when we create a `Pusher` object, which is the one we'll use later to notify our clients:

````python
from solidwebpush import Pusher

# This will automatically create a Public key for you
# and store it in a .PEM file. Note: the next time the
# key won't be created and the value stored in the .PEM
# file will be used instead.
pusher = Pusher()
# And then, let's get our Public Key ...
print pusher.getUrlB64PublicKey() #... as a UrlSafe-Base64-encoded string
````


Copy this string and paste it into the _**main.js**_ file:
````javascript
//main.js (line 24)
const applicationServerPublicKey = '<Your Public Key>';
````


And finally, suppouse one of our clients, after registering and subscribing its serviceWorker(_sw.js_), has sent us the following subscription object:

````text
{"endpoint":"https://fcm.googleapis.com/fcm/send/cOZ80twUe2I:APA91bFWFWTIJzD3B7YHCBKzpSD_KfFe5a_XOo0gZDhGX1JYBwtY6UtNVyCXVt0Z2Fd4iOb9SLSOo1WGBclMaWoDFYMcmh7EhlXd-OJXpWK-gAph0cO1OQPrIqCQ_W0C-XJ0fUsqpXU_","keys":{"p256dh":"BMb7ie9TlYqIUcA52gQBXqKFleWoqHnXPOkvlgKGd2Mw4nnEMhII7VwB41xp0T70VrZb0w4LoP4Cn7ccD0zEtmA=","auth":"EKID_2FLZ4uJg6zSHB4psA=="}}
````

And we want to send him a "Hello World" notification, this could be easily done as follows:

````python
from solidwebpush import Pusher

subscription = '{"endpoint":"https://fcm.googleapis.com/fcm/send/cOZ80twUe2I:APA91bFWFWTIJzD3B7YHCBKzpSD_KfFe5a_XOo0gZDhGX1JYBwtY6UtNVyCXVt0Z2Fd4iOb9SLSOo1WGBclMaWoDFYMcmh7EhlXd-OJXpWK-gAph0cO1OQPrIqCQ_W0C-XJ0fUsqpXU_","keys":{"p256dh":"BMb7ie9TlYqIUcA52gQBXqKFleWoqHnXPOkvlgKGd2Mw4nnEMhII7VwB41xp0T70VrZb0w4LoP4Cn7ccD0zEtmA=","auth":"EKID_2FLZ4uJg6zSHB4psA=="}}'

pusher = Pusher()
pusher.sendNotification(subscription, "Hello World")

raw_input()

````
cool, uh?


Why is there that `raw_input()` statement at the bottom? it is required in this example because the `sendNotification` method is non-blocking. And... Why is that desirable? if `sendNotification` were blocking, it would block the server's "main loop" every time it sends notifications to clients! that's why it runs within a separated thread.

**Note:** these and more examples can be found inside the _"examples"_ folder.



---
## 3. Good to know...

In the "real world", subscription objects are going to be sent to our server via HTTP requests (probably using AJAX), and they will be stored along with the user session ID so that, later, when we need to notify a client, we do so by his session id (and not his subscription object). Fortunately, _solidwebpush_ also does this for us, as shown in the following example:

````python
# SERVER CODE
...
from solidwebpush import Pusher
...

pusher = Pusher()

#Note: assuming messages are being sent via HTTP POST
# and the session token (session_id) is stored
# as a cookie in the client's device.
...
elif POST["action"] == "subscribe":
pusher.newSubscription(
COOKIE["session_id"],
POST["subscription"]
)
elif POST["action"] == "unsubscribe":
pusher.removeSubscription(
COOKIE["session_id"]
)
...

# it's worth noting that you can also
# send a dict object instead of a string.
# solidwebpush will convert it into a
# JSON string before pushing the notification.
msg = {
"title": "Notification Title",
"body": "Hello World"
}
#notifying user X
pusher.notify(user_X_session_id, msg)

#or if you want to,
#notify all users
pusher.notifyAll(msg)

...
````
When `Pusher`'s `newSubscription` is called for the very first time, a sqlite-database file will be automatically generated ('subscriptors.db' by default) to store all these subscriptions for us. Later, when we use a method like `notifyAll` (or `notify`), _solidwebpush_ will push the notifications using the information that is stored there.

Finally, I highly recommend you to read the documentations for a "more in depth" understanding of the package. For instance, `newSubscription` and `notifyAll` can receive an [optional] parameter to specify a group ID. As shown below:

````python
...
#new subscription for <session_id>, which belongs to "group 13"
pusher.newSubscription(session_id, subscription, 13)

...
#notifay all members of "group 13"
pusher.notifyAll("Hello World", 13)
...
````

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

solidwebpush-1.1.0.tar.gz (9.9 kB view hashes)

Uploaded Source

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page