Skip to Content
Vasu D.

14 mins read


Quickstart Python REST APIs with Flask

In this step-by-step tutorial, we will build CRUD REST APIs using Python's Flask module. Flask is a micro-framework for web development.


Introduction

Namaste all 🙏, in this blog post we'll implement a REST APIs that performs the CRUD operations using Python framework Flask. CRUD is short for the following operations :

  • Create : Creating a record in the underlying database
  • Read : Reading records from database
  • Update : Updating a record in database
  • Delete : Deleting a record from database

Before we move ahead, make sure you are done with these steps :

  1. Python : Have python installed on your system. If you don't have it already, install the latest version of Python from this guide.
  2. PIP : Most likely you will have it installed with Python itself, make sure it's updated to latest version by running the following command :
    pip install -U pip
  3. REST API Client : You'll need a client to make requests to the REST APIs that you are making. We recommend installing Postman, but if you are a power user, feel free to use cURL 🤓. We'll be using Postman for this article.

Installing Flask

Flask is a lightweight Python Framework built for rapid development and it is quite easy to use. Because flask isn't a builtin python module, we'll need to install it on our system. You can do so with pip easily, by running the following command :

pip install flask

With this step, you will have Flask installed on your system, and can now move forward with writing actual code.

REST APIs with Flask

In all forms of web development, there are two components :

  • Server : That will contain the logic, and take request as input and send response as output
  • Client : That will make request to the server, and consume the response

With flask, we will be creating the server, that will contain the code for our APIs and will execute on client requests.

Creating a Flask server

Let's first create a simple flask server and an endpoint which will simply return "Hello World!". Create a file named app.py and add the following code to simply create your hello world app in flask.

from flask import Flask
app = Flask(__name__)
 
@app.route('/')
def quickstart():
    return "Hello World!"
 
if __name__== '__main__':
    app.run(
        host="127.0.0.1",
        port="8000"
    )
 

To run the basic API server we just created, we need to run flask. We can do so by following these simple steps :

  1. Move to the directory where you created app.py file
  2. Execute following command on your terminal / command prompt :
    python app.py
    Hit enter!
  3. Now open Postman, and make a GET request to url http://127.0.0.1:8000
  4. You'll see the text "Hello World!" for response.

You can change the port according to you by replacing 8000 with port number of choice.

Setting up a Database

For this tutorial, we will use a serverless, easy-to-use, relational database i.e sqlite3. You are free to use any database of your choice. Let's consider that we are making a blog app. So we'll want to create, read, update and delete the blog posts from our website. For keeping this example easy to understand, we'll create a table with following fields :

  • id : to store a unique id for each blog post
  • title : to store blog's title
  • description : to store blog's content
  • timestamp : to store created_at time of a blog post

Open your app.py and update it with the following code :

from flask import Flask
import sqlite3
 
conn = sqlite3.connect("db.sqlite3")
 
cursor = conn.cursor()
cursor.execute("CREATE TABLE IF NOT EXISTS post (id VARCHAR(36), title VARCHAR(100), description LONGTEXT, created DATETIME)")
conn.commit()
cursor.close()
conn.close()
 
app = Flask(__name__)
app.config['JSON_SORT_KEYS'] = False
 
@app.route('/')
def healthcheck():
    return "Hello World!!"
 
if __name__== '__main__':
    app.run(
        host="127.0.0.1",
        port="8000"
    )

With the above code, out flask app will create a table named post inside our SQLITE db if doesn't exist already.

Note : You don't need to install sqlite3 python library, as it's part of builtin libraries.

Creating Blog post create API

For creating a resource, it's industry standard to use POST HTTP method. So, let's add the code for handling the POST request endpoint which will add the requested post sent inside the body of the request.

import uuid
from flask import Flask, request, jsonify
 
@app.route('/api', methods=['POST'])
def create_post():
    data = request.get_json()
    id = uuid.uuid4()
 
    conn = sqlite3.connect("db.sqlite3")
    conn.row_factory = sqlite3.Row
 
    cursor = conn.cursor()
    cursor.execute(f"insert into post (id, title, description, created) values ('{id}','{data['title']}','{data['description']}','{data['created']}')")
    cursor.execute(f"select * from post where id='{id}'")
 
    values = cursor.fetchall()
    conn.commit()
    cursor.close()
    conn.close()
 
    post = [dict(i) for i in values]
 
    return jsonify({
        "status": True,
        "message": "Post is created successfully!",
        "post": post
    })

The above code will add the post inside the post table in SQLITE and on successful execution this will return the post which is created with the unique id and the message "Post is created successfully!". Hit the endpoint http://127.0.0.1:8000/api with the post request and with the body similar to this,

{
  "title": "Dummy blog post!",
  "description": "Lorem ipsum dolor sit amet, consectetur adipisicing elit.",
  "created": "2022-10-10 12:00:00"
}

On making a request to the endpoint, you should get a response like this :

{
  "status": true,
  "message": "Post is created successfully!",
  "post": [
    {
      "title": "Dummy blog post!",
      "description": "Lorem ipsum dolor sit amet, consectetur adipisicing elit.",
      "created": "2022-10-10 12:00:00"
    }
  ]
}

Creating Blog post read API

For fetching a list/single resource, it's industry standard to use GET HTTP method. To fetch all the records, add the following code which will simply return the list of posts inside the table.

import uuid
from flask import Flask, request, jsonify
 
@app.route('/api', methods=['GET'])
def list_posts():
    conn = sqlite3.connect("db.sqlite3")
    conn.row_factory = sqlite3.Row
 
    cursor = conn.cursor()
    cursor.execute("select * from post")
    values = cursor.fetchall()
    cursor.close()
    conn.close()
 
    posts = [dict(i) for i in values]
 
    return jsonify({
        "status":True,
        "posts":posts
    })

The above code will get a list of all blog posts inside the post table in SQLITE. Hit the endpoint http://127.0.0.1:8000/api with the get request.

On making a request to the endpoint, you should get a response like this :

{
  "status": true,
  "posts": [
    {
      "title": "Dummy blog post!",
      "description": "Lorem ipsum dolor sit amet, consectetur adipisicing elit.",
      "created": "2022-10-10 12:00:00"
    }
  ]
}

Creating Blog post update API

For update a resource, it's industry standard to use PUT HTTP method. Now, to update the existing post this code below will do the trick.

import uuid
from flask import Flask, request, jsonify
 
@app.route('/api', methods=['PUT'])
def update_post():
    data = request.get_json()
 
    conn = sqlite3.connect("db.sqlite3")
    conn.row_factory = sqlite3.Row
 
    cursor = conn.cursor()
    cursor.execute(f"update post set title='{data['title']}',description='{data['description']}',created='{data['created']}' where id='{data['id']}'")
    cursor.execute(f"select * from post where id='{data['id']}'")
    values = cursor.fetchall()
    conn.commit()
    cursor.close()
    conn.close()
 
    post = [dict(i) for i in values]
 
    return jsonify({
        "status":True,
        "message":"Post is updated successfully!",
        "post":post
    })

The above code will update the blog post's title, description, created based on the blog post's id. Hit the endpoint http://127.0.0.1:8000/api with the put request and with the body similar to this,

{
  "id": "56ae506e-8ba7-46c5-853d-6924c89ab4e6",
  "title": "how to correctly lorem ipsum",
  "description": "Lorem ipsum dolor sit amet, consectetur adipisicing elit. Rem perferendis pariatur nobis culpa voluptatem nam sunt sit repudiandae!",
  "created": "2022-11-10 12:00:00"
}

On making a request to the endpoint, you should get a response like this :

{
  "status": true,
  "message": "Post is updated successfully!",
  "post": [
    {
      "id": "56ae506e-8ba7-46c5-853d-6924c89ab4e6",
      "title": "how to correctly lorem ipsum",
      "description": "Lorem ipsum dolor sit amet, consectetur adipisicing elit. Rem perferendis pariatur nobis culpa voluptatem nam sunt sit repudiandae!",
      "created": "2022-11-10 12:00:00"
    }
  ]
}

Creating Blog post delete API

To delete a resource, it's industry standard to use DELETE HTTP method. Let's code the endpoint for deleting our blog post.

@app.route('/api', methods=['DELETE'])
def delete_post():
    data = request.get_json()
 
    conn = sqlite3.connect("db.sqlite3")
    cursor = conn.cursor()
    cursor.execute(f"delete from post where id='{data['id']}'")
    conn.commit()
    cursor.close()
    conn.close()
 
    return jsonify({
        "status":True,
        "message":"Post is deleted successfully!"
    })

The above code will will delete a post from the database table based on the blog post's id specified in request body. Hit the endpoint http://127.0.0.1:8000/api with the delete request and with the body similar to this,

{
  "id": "56ae506e-8ba7-46c5-853d-6924c89ab4e6"
}

On making a request to the endpoint, you should get a response like this :

{
  "status": true,
  "message": "Post is deleted successfully!"
}

Frequently Asked questions

Is Flask harder than Django ?

Flask is easier to learn than Django. Flask is a microframework, which means it doesn't have a lot of features that are included by default in Django. This makes it easier and faster to learn.

Is Flask a microservice ?

Flask is not a microservice. However, you can use Flask to build microservices.

It has many reasons for being popular. Flask is very easy to learn, it's lightweight, fast and easy to deploy as well.

Is flask suitable for production ?

Yes! Flask is suitable for production as well. Many companies have been using Flask in production for years.

Which companies use Flask ?

Flask is used by companies like Netflix, reddit, CRED, trivago, etc.

Ending Notes

And that's it, this is how easy and simple it is to create a REST API for CRUD operations in Flask. There is also a flask-restful library which abstracts some of the hassles with plain flask for you. We recommend exploring it as well.

We've added the complete code for this exercise in the end. Happy Learning!

Flask CRUD REST APi Boilerplate

After all the endpoints we've made, this is how the final app.py should look like. You can use this as CRUD API boilerplate as well.

import sqlite3
import uuid
from flask import Flask, request, jsonify
 
 
conn = sqlite3.connect("db.sqlite3")
cursor = conn.cursor()
cursor.execute("CREATE TABLE IF NOT EXISTS post (id VARCHAR(36), title VARCHAR(100), description LONGTEXT, created DATETIME)")
conn.commit()
cursor.close()
conn.close()
 
 
app = Flask(__name__)
app.config['JSON_SORT_KEYS'] = False
 
 
@app.route('/')
def healthcheck():
    return "Hello World!!"
 
 
@app.route('/api', methods=['POST'])
def create_post():
    data = request.get_json()
    id = uuid.uuid4()
 
    conn = sqlite3.connect("db.sqlite3")
    conn.row_factory = sqlite3.Row
 
    cursor = conn.cursor()
    cursor.execute(f"insert into post (id, title, description, created) values ('{id}','{data['title']}','{data['description']}','{data['created']}')")
    cursor.execute(f"select * from post where id='{id}'")
 
    values = cursor.fetchall()
    conn.commit()
    cursor.close()
    conn.close()
 
    post = [dict(i) for i in values]
 
    return jsonify({
        "status": True,
        "message": "Post is created successfully!",
        "post": post
    })
 
 
@app.route('/api', methods=['GET'])
def list_posts():
    conn = sqlite3.connect("db.sqlite3")
    conn.row_factory = sqlite3.Row
 
    cursor = conn.cursor()
    cursor.execute("select * from post")
    values = cursor.fetchall()
    cursor.close()
    conn.close()
 
    posts = [dict(i) for i in values]
 
    return jsonify({
        "status":True,
        "posts":posts
    })
 
 
@app.route('/api', methods=['PUT'])
def update_post():
    data = request.get_json()
 
    conn = sqlite3.connect("db.sqlite3")
    conn.row_factory = sqlite3.Row
 
    cursor = conn.cursor()
    cursor.execute(f"update post set title='{data['title']}',description='{data['description']}',created='{data['created']}' where id='{data['id']}'")
    cursor.execute(f"select * from post where id='{data['id']}'")
    values = cursor.fetchall()
    conn.commit()
    cursor.close()
    conn.close()
 
    post = [dict(i) for i in values]
 
    return jsonify({
        "status":True,
        "message":"Post is updated successfully!",
        "post":post
    })
 
 
@app.route('/api', methods=['DELETE'])
def delete_post():
    data = request.get_json()
 
    conn = sqlite3.connect("db.sqlite3")
    cursor = conn.cursor()
    cursor.execute(f"delete from post where id='{data['id']}'")
    conn.commit()
    cursor.close()
    conn.close()
 
    return jsonify({
        "status":True,
        "message":"Post is deleted successfully!"
    })
 
 
if __name__== '__main__':
    app.run(
        host="127.0.0.1",
        port="8000"
    )

Looking for a Python Expert? Let's Collaborate!
Get in Touch