Okay, so before we start writing any code, you might be asking what are the prerequisites to be able
to follow along with this tutorial?
So the first thing you need is to install Python on your machine.
And then you would know the basics such as how to create variables, how to write if else statements,
and how to create functions.
That's it for the Python section, and some optional prerequisites would be how to write HTML, CSS
and JavaScript.
So we'll be using HTML for the markup, CSS for styling, and JavaScript for some interactivity on the
browser.
But if you have never worked with any of them, that's fine.
We'll just see this in action and I'll actually try to walk you through it.
Um, so before we try to write any code, let's just see the application overview so that we know what
we're going to have at the end of the day.
So we will need basically two different files.
One for our back end logic which is going to be our Python file and one for the UI, right, which is
going to be our template index dot HTML file.
And inside this we will have some styling with CSS and some interactivity with JavaScript.
And in the back end we will need two different packages, which is going to be for real time communication,
and then the flask framework so that we can really render our UI.
I know this might look pretty complicated, but it is actually pretty simple.
And we'll see this in action.
And then here in the UI you will also be using Socket.io so that we can send events and communicate
with the back end.
But as I said, uh, don't worry, this is not really complicated.
We'll just see this in action.
So with that in mind, the very first thing I have done is to create an empty folder on my desktop,
and I just call it as Python Chat app.
You can really call this anything and just open it up in VSCode.
Now we would like to create an A terminal.
Right.
And here we would like to create what we call the virtual environment.
So in Python development whenever you create a new project you basically most of the time create a virtual
environment so that you have all the packages, uh, and dependencies put into that environment and
not in your machine.
Right.
So let's say this is your machine, right?
This is your laptop or your PC, whatever that is.
Um, and whenever you want to create a new project, you basically create a new virtual environment,
right.
And let's see how we can create one.
So it's going to be a little bit different both in Python, I mean both in Mac OS, Linux and uh, windows.
So if you are on windows just like me, go ahead and say Python dash m Venv VM.
But if you are on Linux or Mac OS you would say Python three.
Re.
And if you just go ahead and run this, this is going to create a folder which is going to be your virtual
environment.
Right.
Now what does that mean.
So here we say uh like by using the Python we say run a module as a script with this flag.
This is not really too much important, but here we are using the Venv module to be able to create an
environment.
And this is the name of the folder folder that we would like to create.
So if you go ahead and delete this and say v three or really anything, and this is going to be the
folder name that it creates, the first one is the module and then the name of that virtual environment.
Okay.
So let's just go ahead and delete this and have it as Venv Venv.
This is the convention that we use most of the time.
And let's just say don't show this again okay.
Now what do we want to do next is to create our files let's say App.py.
And we would like to create the index HTML under our templates.
Let's say index dot HTML.
And let's scaffold this up just by doing that and let's say h1 here.
This says Python chat app.
And we can even put this as our title.
Right.
And let's capitalize these words okay.
Now that we have created our environment, we'd like to activate it and install our packages.
So if you are on windows you would say Venv right.
Just go into that folder, go under the scripts right and then activate, run this file, let's say
activate and run it.
Now here we can see, uh, this has been activated.
If you get this green color, uh, it means it is activated.
Let's deactivate it.
This is how we can do it.
And if you are on macOS or Linux, you would say, uh.
Source venv.
Uh, slash bin and activate.
Okay.
And that would be activating it as well.
Since we are on windows, this is what we're going to write.
And now let's try to build this app dot Pi so that we can render our index.html file.
But as I said to be able to make that work we need this flask package right.
So let's go ahead and install that.
We will say pip install and pip is the package manager for Python.
When you install it it by default comes with it.
But if you don't have it and this is how you can check if you have it or not, you would say pip dash
dash version.
And if you if you can get this kind of output with the version, that means it is installed.
But if you don't have it, you should install it as well, which is pretty simple.
Now I'll say pip install flask and flask underscore socket.io.
So this is going to go ahead and install those packages and put it in our virtual environment.
Um, let's just wait for this to complete, okay?
There we go.
It has been installed.
Now, we'd like to build our Python file so that we can render this in the first place.
Let's go ahead and grab our imports.
So I'll say from flask we would like to import the flask render template as well as the request.
And we'll be using all of them.
Let's say also from flask underscore scikit io package.
We'll take the get the scikit io as well as the image.
Now we'll also be using the random package which is coming from Python by default.
Let's say we would like to create a flask app.
This is how we can do it.
And we can create a new instance with this.
And now we'll just say if a user visits this home route we would like to return.
And you should have this indentation.
Uh, first we need to get the index function right?
Okay.
So let's just say when someone visits this route, we would like to run this function which is going
to go ahead and return.
And let's indent this render template of index dot HTML.
And so what this says um delete this.
Bring this back.
I think this shouldn't be indented.
Right.
If you just do it here, this says uh, you don't need this, uh, indentation for this decorator.
Okay.
Now we also want to say if the underscore underscore name is equal to and just make sure you have two
underscores.
If it is equal to main and again two underscores we would like to run this uh flask application.
Right.
So we'll say socket.io run and put the flask app into it.
So this is how we can initialize socket and flask, uh, in our application.
Now let's try to run this file.
We'll say Python app.py.
And again like one last time, if you are on macOS or Linux you would say Python three.
Okay, let's run this here.
It says development.
Uh server started at this port.
Let's click that.
Here we can see we can get the output that says Python app which is coming from our template.
Right.
Okay.
Now we would like to first uh, handle the entire backend logic, which is going to be uh, with the
socket.io mostly.
Then we're going to go ahead and build the UI and finally deploy this application.
Now, if you have never worked with scikit io, let's just see some diagrams so that we can really understand
it.
Okay.
So let's say we have a bunch of different users and we want to have some kind of communication that
is working in real time.
So we will have our server that is utilizing scikit io.
And this is event based.
What that means is that you can send events to the server saying, like, I just connected and server
will get this event and um, maybe just broadcast it to everyone here.
It's going to say, hey, this user just connected and this is going to be in real time.
These users don't like do not have to send any requests.
So they are not going to say, hey, could you just tell me who is connected so they don't need to send
that request?
Whenever an event is coming, it is just going to immediately, uh, just inform all the clients that
are connected.
Okay.
Now let's just say this user is connected here.
It's going to say, hey everyone, this user just disconnected.
And since you are building a group chat, right, everyone can just, uh, communicate in real time
here.
This user can say, hey, I just want to send a message and this is going to say, hey, there is a
new message from this user to every one of you guys.
And I think now you get the point And we'll have a bunch of different event types, right?
For the connection, disconnection, uh, sending messages and updating usernames.
Now let's just see some kind of like, um, like example.
Right.
So here this user says I am just connecting.
This is going to be the event name.
Let's say uh, let's say hey I just connected and this is going to send user joined to every user.
Right.
So there's always a man in the like man in the middle right.
This user doesn't immediately says uh hey guys I just connected.
Instead it just less than server.
No.
So that server will navigate it to everyone efficiently.
And here again a different example here.
This says I am just sending a new message.
And uh it would send the message content here.
It maybe it says hello guys.
And this is going to say hey guys, uh, you have a new message and this is the message content.
So I hope this makes sense.
That was a long explanation, but let's just see the UI as well.
When someone joins, we're going to get this system message here.
It says this user just joined the chat and we can see the messages.
Someone left the chat and we can even update our username.
And it's going to says like it's going to say, hey, this user just updated their name to this new
name.
Okay.
So with that in mind, let's just try to build all these events and just make that work.
So above the first route we'll take to create the Socket.io event.
And here we'll just say Socket.io dot on connect.
Now whenever you see this dot on you should just know that we are listening for something, right?
So we are listening for let's say for the connect event.
Okay.
When someone connects, we would like to handle this.
So we'll just go ahead and just say def handle connect.
You can call this function anything.
And here the very first thing we would like to do is just generate a random username.
So I'll just say user name is going to be equal to f string.
And we will say user underscore random package dot rand int and the range.
So it could be from 1000 to 9 999.
Right.
And now we would like to also create a random gender okay I'll say gender is going to be random dot
choice from an array.
This could be either a girl or boy.
And obviously this should be a string.
Okay.
Now you might be asking why don't we use male and female now?
It's because we'll be using an API that specifically wants you to use a girl or boy.
Okay, I'll just even put this if you want to test this out, start, but let me just copy this and
show this.
Okay.
So if you go with the boy in the URL, this is going to give you a boy profile image.
But if you go with the girl this is going to give you a girl profile image obviously, right.
And depending on this randomly generated gender we'll get a like an avatar URL.
Right.
And we also want to store all the connected users into a Python dictionary.
So let's say users.
And here we can put a comment above.
We'll say Python dictionary.
This is and store connected users.
Key is going to be the scikit io okay scikit id I was going to say key is scikit id.
And then the value is going to be the username and avatar URL.
And we'll you'll just see this in action.
Okay, now that we have the username and gender, let's try to create an avatar URL as well.
I'll say avatar underscore URL, which is going to be equal to again this f string.
And we can put the entire URL as it is.
Right.
And the only dynamic part is going to be this gender field.
So let's say gender just like this.
And then the username.
Okay so with that now we have the avatar URL as well.
Now what do we want to do is just store this user info into this user's dictionary.
So here we'll say user's request dot set which stands for the ticket ID.
And this request is coming from the flask.
If you remember right.
And here we'll just basically say this is going to be a dictionary or an object.
We'll say username field.
Is going to be equal to this username variable that we created.
And then the avatar is going to be equal to the avatar URL field that we just created.
Right.
And now that this user is connected we would like to notify all the clients about this new user.
And this is where we're going to use the emit function.
Right.
So we have stored it in the database or in the server.
We would like to now notify everyone with this new connection.
We'll just say user joined.
Right.
You can call this anything like user connected.
It could be but this is the name that I'll be going with.
I'll just say user name.
And you'll basically just giving the username as well as the avatar URL of this user.
And here we'll just say broadcast is going to be true.
So that it lets everyone know about this event.
Right.
Just like what we have done here, it's going to go ahead and just tell to everyone this user just connected.
Okay.
The very last thing we thing we would like to do is just give a random name for this user, right?
So we have created the username, but we also need to uh, just notify that user about the username.
So we'll say emit is going to be set underscore user name.
Uh we can just say here is your username.
Okay.
So I hope this makes sense.
This is the entire function where we handle the connection.
And same is going to be for the this connection right.
We will just delete it from the uh from our store.
And then just let everyone this user just left.
Okay.
Let's go ahead and try to do it.
Or even you can pause the video and just have it as a challenge.
So I'll say at scikit io dot on disconnect.
So this is the special name that we get from scikit io.
We'll say def handle.
This connect method, and we would like to basically delete it from the, uh, from the dictionary so
you can do it I think like this.
But what I'll be doing is to store it in a variable.
Let's say user users dot pop, right?
We'll just delete it.
And this is the ID of that.
And in case it is undefined we'll just return none so that we don't really have any errors and our code
doesn't crash.
We'll say if we have the user you'd like to emit this, uh, user left event, and we would like to
give the username here.
I'll just say user name.
Which is going to be this user's username.
Right.
And we'll take the broadcast this so that everyone knows about this right now.
Let's save I think this is a bit too much indentation okay.
It should be like this.
So this is how we handle the connection and disconnection.
Now we have two different things left, which is going to be to be able to send the message and update
the username.
So we'll just say Socket.io dot on.
You will listen for any, any incoming new messages.
Right.
Then we'll try to render this or handle this with the function let's say handle message which is going
to take the message itself.
So we can call call it as the data.
And here we would like to first find the user.
So users dot get and we'll say request dot socket ID.
And we'll say if we have the user then we would like to just emit an event to everyone.
We will say new message and we're going to give the basically profile image of that user.
Right.
When there is a new message coming, we will get the profile, uh, like avatar URL.
The username as well as the message content.
Okay, let's just do it.
We'll go into the second argument which is going to be the data body.
So we'll say username.
Um get the avatar.
And we also want to get the message content which is going to be data.
We can just have the message out of it.
And finally we'll just say broadcast to be equal to true.
And that's going to be it for the send message event as well.
The other one is going to be to be able to update the username.
So the first thing we would like to do again just listen to it Socket.io on.
And the event name is going to be update underscore username.
Right.
And we'll just handle this let's say def handle update username.
And we're going to get the data which is going to basically have the new username.
So let's say old underscore username.
We can just grab this from the user's dictionary.
We'll say request dot set, which is going to be the socket ID.
And from this user we would like to get the user name.
And let's get the new username which is basically the data that user sends us.
From this we would like to get the username.
And we would like to update this old name to be the new username.
So here we'll just say from the user's request dot set we just find the this current user.
And we would like to update their username to be this new username.
And let's notify all clients about the username change.
So we'll just go ahead.
Let's say emit.
And the event name could be username underscore updated.
And let's close this off.
Put our second object which is going to be the data that we're going to grab from the client.
So let's say old underscore username is going to be equal to the old username.
and same for the new one.
Now let's just broadcast this to everyone.
Okay.
So basically that's it for the entire App.py file.
Let's quickly try to reiterate what we have done.
We have installed our packages right.
We just got our imports.
And we have created a flask app where we can use it to be able to render our template.
And we got the Socket.io instance with the user's dictionary so that we can keep track of the connected
users, where the key is going to be the socket ID, and the value is going to be the username and avatar
URL, right?
Okay.
So we are listening for the connect event.
How do we understand this?
Uh, like if you are listening or not, it is because we have the on method, right?
So sick io on.
Listen for the connection.
This connection send message and update username.
So all these events will be coming from the user.
So if you take a look at the diagram, it is actually pretty self-explanatory, right?
User sends you this event and you're listening for the event itself.
When there is a new connection, what you do basically generate all these information randomly, then
store it on the back end so that, you know, like which user is online, which is not.
And you say like, hey everyone, I'm just notifying you with this broadcast is equal to true.
And this user just joined and we say, hey, this is your, uh, random username.
And if you really want to, you can update it and so on and so forth.
For the disconnection, we just let everyone that this user is disconnected and sending new messages
as well as updating the username.
So that's going to be it for this file.
Next we're going to build our UI.
So let's go ahead and save this file.
And I will see you in the next section.