Flask Introduction
Introduction
Create folder and virtual environement
Python is a high-level, general-purpose programming language that is used in a wide variety of applications. It's known for its clear and readable syntax, and for its ability to work with a large number of libraries and frameworks.
Flask is a Python framework used to create web applications. It's characterized by being lightweight and flexible, making it ideal for creating simple and fast web applications. Flask allows creating web applications through the use of routes, views and templates, making it easy to learn and use.
In the specific case of this post, Flask is used as a framework to create a basic web application, and it explains step by step how to configure the virtual environment and create a simple Flask application that displays a message on the home page. It also covers other basic concepts like routing, templates and static files in Flask.
Installing Python
Starting a Flask Project
Open a terminal, create a directory, and then create the virtual environment:
mkdir myproject
cd myproject
python3 -m venv .venv
If you see the "(venv)" on the left, it means you have successfully created a virtual environement.

If you fall in any throuble, you can review the documentation: https://docs.python.org/3/library/venv.html
If Python is not recognized, you probably need to add it to your environment variables. To do this on Windows, click the Windows key, type "env" and press enter.
Double click on "PATH" and then paste the path where you have Python. It should look like the image:
venv in this case is the virtual environment we specified before. If instead of running py -3 -m venv venv
we ran py -3 -m venv fafa
, now we should look for the scripts folder inside fafa. It's the name we gave it. By default it's usually left as "venv" which means "virtual environment" in English.
Install flask
pip install Flask
Coding
(I recommend downloading a code editor like Visual Studio Code, PyCharm or Atom.)
We create a file with whatever name we want inside the project folder.
touch main.py

Then we write the following code:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return "Hello Shan"
We go back to the terminal and execute:
export FLASK_APP=main.py
Main is called in my case but it can have any name.
$env:FLASK_APP = "main.py"
Run server:
flask run
Access the port that the console tells you and you should have something like this:

Congrats, your first backend running locally 😀
To deactivate the virtual environment we have to type deactivate
from the root folder. BE CAREFUL not to confuse it with deactivate.bat
because when we activated it we ran with .bat but in this case just typing it will deactivate it. Like in the following example:
And notice how the prefix (venv)
disappeared from my console.

Routes
Now we can go back to our code and add a new route:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return "Hello shan"
@app.route('/login')
def login():
return "A login should go here"
Now we navigate to that web and...
HOW NOT FOUND?
I don't know, I felt cheated the first time.
What happens is that we have to run the server again with:
flask run
But it would be really slow to keep executing the server again every time we add code. For this, Flask offers us a solution, instead of executing flask run
we can execute flask run --debug
This will allow us to modify the code and when we save it, we'll refresh the page and see the changes reflected.
⚠️ It can happen that if we have an error in the code, we have to stop the server and run it again.
If it doesn't work and runs, you might have to re-export the app.
Go to the URL and you'll see your page.
Try changing the function name or the route and you'll see that it updates without needing to run everything again.
If you make a mistake in the code, for example you're writing, Flask can show you errors on the page or terminal. But as long as you reload when this happens, it will keep working fine (as long as the code is written correctly).
I clarify this mainly so you don't worry if it looks bad when you're typing.
Variables
You can pass variables to routes in the following way:
@app.route('/login/<user>')
def login(user):
return "Hello " + user
And now if we navigate to the route /login/shan
It returns the following:

You can force variables to be of some type
, for example like this:
@app.route('/dias/<int:date>')
def fecha(date):
return 'this is an int: ' + date
Notice how I put an int right in there.
That's so it only takes int as variables.
Now, this won't work for us. Because I'm returning a return that has a string + int and that can't be combined in Python.
I recommend you try it so you understand what I mean ;)
TIME FOR MATE 🧉
METHODS
Let's see how we can send HTTP METHODS. This is the desired action on the route we want to make.
HTTP methods are verbs that indicate the action to be performed on a resource provided by a server. The most commonly used methods are:
GET
: used to request data from a specific resource. Should not have side effects on the server.POST
: used to send data to create or update a resource on the server. Can have side effects on the server.PUT
: used to update an existing resource on the server. If the resource doesn't exist, a new one is created.DELETE
: used to delete a specific resource from the server.PATCH
: used to partially update an existing resource on the server.
We add in an array, the methods we want to execute that function:
@app.route('/user/<id>', methods=['GET', 'POST'])
def fecha(id):
return 'It is this user ' + id
For now everything is still working great.
When we navigate to the web from Chrome, it made a GET
.
POST
To test "hitting the backend" (communicating with it).
Let's execute the following command:
CURL -X PUT http://localhost:5000/register/user-name
The console should return some error. Because we told our function that it could receive POST and GET. But we didn't tell it that we could receive a PUT to that route.
In fact, in the console where the server is running you'll see strange things.
Let's modify the code to accept a POST.

Therefore now let's execute the following command to test that it works if we send POST or GET:
curl -X POST http//:localhost:5000/register/user-name
We should see something like this in the console:

If you add the GET method, it should also works for you.
I want to highlight that in a very similar way our frontend will communicate when it sends us requests to save to database or do something special.
Different routes, same method, or vice versa.
Now, something very normal in backend is to have the same route, the same path, but for different things.
For example /user
with the POST method creates a user. While the same route /user
with the GET method returns a user.
There are two ways to do this. One is reusing the route but changing the methods it receives. Like this:
@app.route('/user/<id>', methods=['POST'])
def saveUser(id):
return 'Create user ' + id
@app.route('/user/<id>', methods=['GET'])
def getUser(id):
return 'Return user ' + id
Notice how they're almost the same but I changed the method name. Same route, but one function is called getUser()
and the other saveUser()
.
Plus inside "method" one says GET and the other POST.
Another way is to ask with an if what type of request it is. Like this:
@app.route('/user/<id>', methods=['POST', 'GET'])
def saveOrGetUser(id):
if request.method == 'GET':
return 'Create user ' + id
else:
return 'Return user ' + id
I'm more of a fan of the first option. But I use this as an excuse for you to see how I can access the request
inside the method ;)
If you can't access 'request' maybe it's because you didn't import the libraries correctly. Now the first line of code should look like this:
from flask import Flask, request
Forms
To be able to see what we're going to be sending through forms, we can write the following:
To test it we're going to have to throw the following command:
@app.route('/form', methods=['POST'])
def formulario():
print(request.form)
Notice how I specify that it's a POST method. Because by default, routes are created with the GET method. So sending a form wouldn't work for me.
Let's go to a terminal and execute:
curl -d "nombre=shanick&profesion=programador" -X POST http://localhost:5000/form
curl is the tool we're using to send requests to our backend.
-d
is to specify the data we send.
Then the data comes in key-value format. Where nombre is the key. While shanick is the value.
The ampersand, &, is used to concatenate data, we could have sent all we wanted.
-X
is to specify the type of method, in this case POST.
And lastly the route.
And in the terminal you'll find a giant form with everything you wanted. The form.
You can specify what data you want.
@app.route('/form', methods=['POST'])
def formulario():
print(request.form['nombre'])
print(request.form['profesion'])
return 'done'
In the right terminal, from where I sent the command, you'll see that it responds with the 'done' we returned in the method. While in the left terminal, the "server", what you're seeing are the server's prints.
Redirection
If at any moment we want to redirect the user. We can do it through the functions of another path.
@app.route('/estaRuta', methods=['GET'])
def estaRuta():
return redirect(url_for('redirecciona'))
@app.route('/redirecciona', methods=['GET'])
def here():
return 'here'
Let's go by parts.
url_for('')
is a function that returns us the function of where we want to go. Notice that I put 'redirecciona' inside the parentheses, because it's the path '/redirecciona' where we want to send it.
So it's going to take me to what the function here()
does.
redirect()
serves precisely to redirect to the URL we got with the url_for()
method.
And that's how at any moment we can redirect a user.
If it didn't happen automatically by writing the methods, you have to add the imports manually. Line 1 should look like this:
from flask import Flask, request, url_for, redirect
HTTP Codes
We can return errors to the user. The famous 404
or 403
are good examples.
With abort()
we can achieve this.
First in our first line we import abort.
from flask import Flask, request, url_for, redirect, abort
For example with the following code:
@app.route('/error', methods=['GET'])
def error():
abort(403)
A code like the following:
@app.route('/error', methods=['GET'])
def error():
abort(404)
returns us a 404.
Well, and so with all the codes we need.
Returning HTML
So far we've only returned very vague pages to the user, practically errors or some other message. But we can return a complete HTML page.
First we have to create a /templates
folder and inside a file that we want to return, for example, myPage.html

In our first line of code we have to import this new function.
from flask import Flask, request, url_for, redirect, abort, render_template
That's how it should look so far.
The code should look something like this:
@app.route('/page', methods=['GET'])
def aca():
return render_template('myPage.html')
The files should look like this:
It's very important that the name we write inside the render_template('') function is exactly the same as the file we created inside the templates
folder, we also can't change the folder name.
The HTML file contains the following:
<H1>This is your page</H1>
(very basic)
If we see it, congratulations, you returned your first HTML
Returning JSON
Something very common is wanting to return a JSON from the backend. Fortunately in Flask this is quite simple, and is done between braces following JSON format. So there's not much to it.
@app.route('/json', methods=['GET'])
def getJson():
return {
"userName":'shan',
"email":'shan@gmail.com',
"age": 23
}
Notice how '23' is an int
while the rest of the data are string
this will help us in the client to use it as we need.
The page should return us something like this:

SQL Database
To use SQL
in the project, we have to integrate the SQL connector for Python.
First we go to the console where our project runs, and press ctrl + C
In the console we execute the following command:
pip3 install mysql-connector-python
Depending on where you are, the command might be pip
instead of pip3
depending on your operating system.
And finally we start the server again. flask run
Now we go to the beginning of our script and import mysql connector.
import mysql.connector
⚠️ It might happen that when you write `mysql` it's still not recognized. Some IDEs can help you install it, you hover over it and they usually tell you how to solve it.
We continue:
We start the database and the connector in our code and start the cursor:
sqlRepository = mysql.connector.connect(
host="localhost",
user="ninshan",
password="123456",
database="kettoDb"
)
cursor = sqlRepository.cursor()
In this case we create a method in the path /game
that returns us a JSON with the key games and inside contains everything it got from the SQL query select * from Games
, this query would be something like 'take everything that's inside the Games table'
@app.route('/game')
def getGames():
cursor.execute('select * from Games')
games = cursor.fetchall()
return {
"games": games
}
And in the same path, but with the POST
method, I'm inserting into the Games
table, two variables. gamename and mode.
@app.route('/game', methods=['POST'])
def setGames():
gamename = 'some name'
mode = 'smash'
sql = "insert into Games (gamename, mode) values (%s, %s)"
values = (gamename, mode)
cursor.execute(sql, values)
sqlRepository.commit()
return 'done'
This if we try to run it won't help us much because we don't have any database really created.
That's why I'm going to create a datasource with my IDE to be able to really interact with a DB.
Pay attention that the configuration names match those we put in our sqlRepository
variable.
Last updated