4Geeks logo
4Geeks logo

Bootcamps

Explore our extensive collection of courses designed to help you master various subjects and skills. Whether you're a beginner or an advanced learner, there's something here for everyone.

Academy

Learn live

Join us for our free workshops, webinars, and other events to learn more about our programs and get started on your journey to becoming a developer.

Upcoming live events

Learning library

For all the self-taught geeks out there, here is our content library with most of the learning materials we have produced throughout the years.

It makes sense to start learning by reading and watching videos about fundamentals and how things work.

Full-Stack Software Developer - 16w

Data Science and Machine Learning - 16 wks

Search from all Lessons


LoginGet Started
← Back to Lessons

Weekly Coding Challenge

Every week, we pick a real-life project to build your portfolio and get ready for a job. All projects are built with ChatGPT as co-pilot!

Start the Challenge

Podcast: Code Sets You Free

A tech-culture podcast where you learn to fight the enemies that blocks your way to become a successful professional in tech.

Listen the podcast
  • REST

  • Python

    Flask

  • APIs

Edit on Github

Building RESTful API's using Flask

Now let's talk about Flask

By now, you should already know what a REST API is, if you don't, I recommend you read about it here.

As a very brief summary, building an API in a RESTful way means that you have to build your URL endpoints grouped by "resources". A resource is something you want to manage, e.g: Student, User, Car, etc. A resource is something similar to a database table, but we call them "resources" because of a few exceptions.

Here is an example of RESTful API endpoints to manage Students:

MethodURLDescription
GET/studentShould return all the students
GET/student/1Should return a single student with the id=1
GET/cohort/1/studentsShould return all the students from the cohort with id=1
POST/studentShould create a new student
PUT/student/1Should update the information of the student with the id=1
DELETE/student/1Should delete the student with id=1

Take a look at the URLs; they follow a pattern. After a while, the endpoints will speak for themselves, becoming self-explanatory. You will be able to guess what they do or even guess some endpoints. That is the whole idea.

👉 You can read more about REST APIs on this 4Geeks Lesson.
Here is a cool 8 min video explaining REST: https://www.youtube.com/watch?v=7YcW25PHnAA

Now let's talk about Flask

Flask is amazing! It is very similar to Node.js Express Server, and that makes it even cooler because you will be able to work with both technologies without much of a learning curve.

Flask is a library for creating web servers and APIs, basically when you run a Python script that contains the following lines, the computer will start listening for HTTP requests:

1from flask import Flask 2app = Flask(__name__) 3 4@app.route("/") 5def hello(): 6 return "Hello World!" 7 8app.run(host='0.0.0.0')

Click to test this code live

Flask Hello-World explained

1from flask import Flask # Here we import the Flask library into our file 2app = Flask(__name__) # Here we create a new instance of the Flask server 3 4@app.route("/") # Here we define the first API path: GET / 5def hello(): # This method will be called when the request is called from any client 6 return "Hello World!" # Flask will return "Hello World!", this could be an HTML string or a JSON string 7 8app.run(host='0.0.0.0') # Lastly we start the server on localhost

In Flask we can add new endpoints by using the @app.route decorator, don't worry if this is the first time you see a decorator, the concept is very simple and here is a 5 min video explaining it.

Adding new endpoints

If you want to add another endpoint to your API that runs when a client calls GET /person you will have to add another block of code like this:

1@app.route("/person") # Here we specify the path for the endpoint 2def handle_person(): # Here we declare a function that will be called when a request is made to that URL 3 return "Hello Person!" # Here we specify the string we want to respond to the client

Specifying the method: GET, PUT, POST, DELETE

If you want your endpoint to answer to POST, PUT or DELETE you can specify that on the decorator like this:

1from flask import Flask, request 2 3@app.route("/person", methods=['POST', 'GET']) # Here we specify that this endpoint accepts POST and GET requests 4def handle_person(): 5 if request.method == 'POST': # We can understand what type of request we are handling using a conditional 6 return "A POST has been received!" 7 else: 8 return "A GET has been received!"

Responding a JSON body

The response can basically be whatever you want as long as it is a string: HTML, JSON, CSS, Images, etc. Just make sure you convert into a string whatever you want to respond.

In the following example we are using the jsonify method to convert a dictionary called person1 into a JSON string before returning it to the client.

1from flask import Flask, jsonify 2 3@app.route("/person") 4def handle_person(): 5 person1 = { 6 "name": "Bob" 7 } 8 9 return jsonify(person1)

The Response Code

The response code is 200 by default and 500 if there is an unknown error. If you want to respond to the client with a different code, you will have to specify it like this:

1from flask import Flask, jsonify 2 3@app.route("/person") 4def handle_person(): 5 content = { 6 "details": "Hey, there has been an error on your request" 7 } 8 resp = jsonify(content) 9 resp.status_code = 400 # Here we change the status code to 400 (typical code for request errors) 10 11 return resp

Another way of changing the response code using a comma ,:

1@app.route("/person") 2def handle_person(): 3 content = { 4 "details": "Hey, there has been an error on your request" 5 } 6 7 return jsonify(content), 400

Handling errors and validations

But what if the request comes with errors? For example: If we have an endpoint to create a person and must specify both the first_name AND last_name but only the first_name was found on the request, this is how we would validate it:

1@app.route('/person', methods=['POST']) 2def create_person(): 3 # POST request 4 body = request.get_json() # Get the request body content 5 if body is None: 6 return "The request body is null", 400 7 if 'first_name' not in body: 8 return 'You need to specify the first_name', 400 9 if 'last_name' not in body: 10 return 'You need to specify the last_name', 400 11 12 return "ok", 200

Defining a model

There are different ways to integrate Flask to a database server, but this time we will be explaining the integration with SQLAlchemy.

There is a great Python library that integrates Flask + SQLAlchemy in a seamless way: Flask-SQLAlchemy. We suggest you read this lesson about SQLAlchemy first and come back here.

To integrate with SQLAlchemy all you have to do is install the package and import it into your files like this:

1from flask_sqlalchemy import SQLAlchemy 2db = SQLAlchemy()

Once it is imported, you can start declaring your database models like this:

1class Person(db.Model): 2 id = db.Column(db.Integer, primary_key=True) 3 username = db.Column(db.String(80), unique=True, nullable=False) 4 email = db.Column(db.String(120), unique=True, nullable=False) 5 6 def __repr__(self): 7 return '<Person %r>' % self.username 8 9 def serialize(self): 10 return { 11 "username": self.username, 12 "email": self.email 13 }

You can add as many models as you like.

Ready to start coding?

We have prepared a boilerplate that you can run yourself in GitHub Codespaces or Gitpod and use it as a base for your project.

Flask Rest Hello: https://github.com/4GeeksAcademy/flask-rest-hello