DEV Community

Cover image for Simple realtime notifications
Max Kolyubyakin
Max Kolyubyakin

Posted on • Originally published at Medium

Simple realtime notifications

We will use Vue.js + FastAPI + Pusher

Let’s all accept the fact that any modern web application can’t live without realtime notifications. If your cool shiny service doesn’t have them yet, there is a 99% chance that it is somewhere there in your backlog.

Today, speed of delivery is the level of quality.

In other words, there is no question WHY, there is another question — HOW?

Target Architecture

Managers must get immediate notifications when Customer orders something

We would want something like that. Let’s briefly discuss details on this E-Commerce example:

  • Our Frontend has 2 portals: Online Store for Customers and CRM for Managers
  • Our Backend has microservices architecture with a message bus for communication between services
  • We have many services in Backend, but only two are important for this example: Orders and Events
  • Backend services are written in everything from Cobol to Go, but for events we want something simple and reasonable like Python
  • We want some free SaaS like Pusher to handle realtime notification complexity for us (we are too greedy to pay from the start and too lazy to work with websockets on our own)
  • We must be able to send the same notification to a group of managers (let them battle for the client!)
  • Notifications need privacy as there may be some sensitive user information (we state that we don’t sell user data, usually).

Proof Of Concept

PoC

For the proof of concept we can simplify everything even more:

  • We don’t care how messages will appear in our Events service — a simple manual script will be totally enough
  • We won’t create complex Authentication/Authorization for Events Auth call as we will test only locally
  • No Fancy UI in Frontend, a simple text notification is fine for PoC

SaaS

Pusher with Pusher Channels seems like a perfect fit for our needs. It offers a generous free plan for getting started: 100 max connections, 200k messages per day, SSL protection, unlimited channels and 99.997% API uptime. There is also a great Pusher Channels Python SDK, which has backends for sync and async code. And last but not least, it’s used by our beloved GitHub.

Pusher also provides the Beams platform for mobile push messages (web is in beta at the moment). If you need to support such kind of notifications, it seems like a great tool to try. Though, you need to be warned that at this moment Python SDK for Beams doesn’t provide support for async code. It doesn’t seem like a big problem as Beams API is pretty simple, but it will take some efforts to integrate.

For the code in the next paragraphs we will use some of Pusher Channels Environment Variables, which can be found in the App Key section of the created application in Pusher Dashboard.

CRM Portal

Let’s start writing code already! Our CRM portal will consist only from one HTML page with the simplest Vue Application inside.

As you can see, the code is pretty simple. We create a Pusher instance with custom authentication endpoint and subscribe it to the private channel private-foobar. If we will open the page right now, authentication will fail and we won’t be able to receive our events. Let’s implement our Events service to fix that.

Events Service

Our service will have the following requirements.

pusher              # Pusher Channels SDK
aiohttp             # Async HTTP client for Pusher Backend
fastapi             # Fast and Modern API Framework
uvicorn             # ASGI server to run our API
python-multipart    # Support for Forms in FastAPI
python-dotenv       # Loading of variables from .env

We will start with initialization of Pusher client:

For local development we need to enable CORSMiddleware with any origin (restrict origins for production usage!). pusher_auth implementation is done according to the Pusher Authentication Specification. We can now run our API!

uvicorn api:app --reload
INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO:     Started reloader process [83155] using statreload
INFO:     Started server process [83157]
INFO:     Waiting for application startup.
INFO:     Application startup complete.

We can now open our CRM Portal and authentication will be successful. Now, we have only one thing left — event generation. We will write the following simple script:

Let’s call it to see if we get the notification in our web Portal. And there it is:
PoC

If we open several tabs with the same CRM portal, we will see that each tab receives “hello world” message.

The concept has just been successfully proved 🥳! Here is the repository for you to play with.

GitHub logo maxipavlovic / chapushillo

Example of using Pusher Channels with Asyncio and FastAPI

Top comments (2)

Collapse
 
khabz profile image
Khabubu Ndivhuwo

Why use pusher instead of using vuex on the client application and sockets on the server side?

Collapse
 
maxipavlovic profile image
Max Kolyubyakin

That's definetly one of the options. But developing a good websockets solution in the backend comes at a much higher cost from both technical and management points of view. In this article I present the idea of not using/maintaining sockets on the server side ourselves. We want any SaaS to do it for us: pusher js client library opens a websocket connection to Pusher cloud backend.

I am not great at frontend, so I can't be 100% sure if it's true, but I guess, Vuex can be used with Pusher in the same way as with any other socket library: stackoverflow.com/a/44336198