Web push notifications are a powerful tool to keep the user engaged even when they are not actively on your web application. In this article, we will explore how to implement web push notifications using the Python Flask framework.
Before we get started, you need to have a basic understanding of Python, Flask, and JavaScript. You will also need to have Node.js installed on your system to use some of the necessary tools.
To implement push notifications, we will follow these steps:
- Set up the Flask server.
- Generate VAPID keys for authentication.
- Manage notification subscription in the client.
- Send notifications from the Flask server.
First, create a Flask project. Start by installing Flask:
pip install Flask
Then, create an app.py
file and set up a simple Flask app:
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def index():
return render_template('index.html')
if __name__ == "__main__":
app.run(debug=True)
Also create a basic HTML template called index.html
in the templates
folder:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Web Push Notifications</title>
</head>
<body>
<h1>Web Push Notifications with Flask</h1>
<button id="subscribe">Subscribe</button>
<script src="app.js"></script>
</body>
</html>
Voluntary Application Server Identification (VAPID) keys are used to authenticate the server that sends notifications. You can generate them using an npm package called web-push
.
Install web-push
:
npm install web-push -g
Generate VAPID keys:
web-push generate-vapid-keys
This command will give you a public key and a private key. Save these keys because we will use them in the Flask server.
In the app.js
file, add the following code to handle the client's subscription to push notifications:
const publicVapidKey = 'YOUR_VAPID_PUBLIC_KEY';
if ('serviceWorker' in navigator) {
send().catch(err => console.error(err));
}
async function send() {
const register = await navigator.serviceWorker.register('/worker.js', {
scope: '/'
});
const subscription = await register.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: urlBase64ToUint8Array(publicVapidKey)
});
await fetch('/subscribe', {
method: 'POST',
body: JSON.stringify(subscription),
headers: {
'content-type': 'application/json'
}
});
}
function urlBase64ToUint8Array(base64String) {
const padding = '='.repeat((4 - base64String.length % 4) % 4);
const base64 = (base64String + padding)
.replace(/-/g, '+')
.replace(/_/g, '/');
const rawData = window.atob(base64);
const outputArray = new Uint8Array(rawData.length);
for (let i = 0; i < rawData.length; ++i) {
outputArray[i] = rawData.charCodeAt(i);
}
return outputArray;
}
Then create a worker.js file in your project's root:
self.addEventListener('push', event => {
const data = event.data.json();
self.registration.showNotification(data.title, {
body: data.message,
icon: 'icon.png'
});
});
Install the pywebpush
package:
pip install pywebpush
Add the following lines to your app.py
to handle subscription and send notifications:
import json
from flask import request
from pywebpush import webpush, WebPushException
VAPID_PUBLIC_KEY = "PUBLIC_VAPID_KEY"
VAPID_PRIVATE_KEY = "PRIVATE_VAPID_KEY"
@app.route('/subscribe', methods=['POST'])
def subscribe():
subscription_info = request.get_json()
return "Subscribed", 201
def send_web_push(subscription_information, message_body):
try:
webpush(
subscription_info=subscription_information,
data=json.dumps(message_body),
vapid_private_key=VAPID_PRIVATE_KEY,
vapid_claims={
"sub": "mailto:you@email.com"
}
)
except WebPushException as ex:
print(f"Error: {repr(ex)}")
@app.route('/notify', methods=['POST'])
def notify():
subscription_info = request.get_json()
message = {
"title": "Title",
"message": "Body"
}
send_web_push(subscription_info, message)
return "Notification sent", 200
Now, you can test notifications by running the Flask app and sending a POST
request to /notify
with the subscription data.
Conclusion
With these steps, you have implemented a simple web push notification system using Flask. This example can be extended and customized to meet the specific needs of your application. Push notifications are a powerful tool for keeping users engaged, and with Flask, implementing them is quite straightforward.