Any website has two parts: a frontend and a backend. The backend handles our logic and data storage and communciates via URLs, but instead of sending web pages, it only sends data.

Now, let’s create something simple with Flask to show a basic backend service in action.

print("Hello Flask")

Motivation

Comic: IRA GLASS: Advice for beginners

Hosted by: Monika Para

Resources

Installation

First, make sure that the following are installed on your device. If not, install them:

  • VSCode
  • Flask Check to see if you have the latest version installed on your device by typing flask --version in your terminal.
  • Virtual Environment This is how Flask will run a local host server
  • Postman This will help us visualize the API requests we make. Make an account using either your UIUC Login or the email you used to make your Github account.

Setting Up Your Project

First, we create a folder for the project

$ mkdir flask-api
$ cd flask-api

After this, we set up flask. This is the framework that actually allows us to make a simple backend by just passing a few functions around.

$ flask run

Workshop

First Task: Making Your First Flask Server

First we import flask and create our web server.

# import flask libraries
from flask import Flask, jsonify, request
app = Flask(__name__)

# flask run -> server runs at http://127.0.0.1:24000/ 
@app.route("/")
def hello():
    return "Hello World!"

Once you have the following code in your app.py file, run python app.py and you should get a message on your terminal saying Server running on http://127.0.0.1:24000/. Navigate to that URL, and you have made your first Flask server - congratulations!

Now if you go to http://127.0.0.1:24000/, it should say Hello, World!. Yay! Now the setup is done and the fun part begins.

Understanding CRUD

CRUD is probably one of the most important concepts in backend development. This acronym refers to the 4 broad actions we do with any web backend. Let’s consider this with Reddit, but you’ll quickly realize that these can apply to any site.

  • Create - Create new data. For example: creating a Reddit post.
  • Read - Look up existing data. For example: looking at a post.
  • Update - Update data that already exists. For example: adding an edit to fix a typo.
  • Delete - Remove existing data. For example: removing a post.

Second Task: Making Your First GET Request

Include the following code before running your server

# mock JSON database of some staff's favorite cats 
fav_cats = [{'name': 'Harsh', 'breed': 'Indian Billi'},
        {'name': 'Mon', 'breed' : 'Calico'},
        {'name': 'Saurav', 'breed': 'All cats!'},
        {'name': 'Drshi', 'breed': 'Maine Coons'}]

@app.route('/favcat', methods=['GET'])
def get_all_cats():
    # @TODO: get all the cat entries
    return jsonify({"list all cats": fav_cats})

This code allows you to create a simple JSON object containing things that make you happy. Now, when we navigate to the /favcat URL on our Flask server, we’ll see the results of our GET request. Now that you have made your own JSON object and URL, you can navigate to http://127.0.0.1:24000/favcat and check it out!

Third Task: GET Request by NAME

The following code snippet creates a GET request so that you can access items in the favcat by NAME:

 @app.route('/favcat/<string:name>', methods=['GET'])
def get_one_cat(name):
    # @TODO: get only ONE cat entry
    return_cat = fav_cats[0]
    for get_cat, get_staff in enumerate(fav_cats):
        if get_staff['name'] == name:
            return_cat = fav_cats[get_cat]
            return return_cat 
        elif get_staff['name'] != name:
            return_cat = "entry does not exist"
    return jsonify({'This staff favorite cat is ' : return_cat})

If you navigate to http://127.0.0.1:24000/favcat/Harsh in your browser, you should be able to see:

{"This staff favorite cat is ":{"breed":"Indian Billi","name":"Harsh"}}.

However, if you replace Harsh with Lou in the URL you will get: {"This staff favorite cat is ": "entry does not exist"}

This just means that we don’t have an item in the array with that NAME. How can we add an entry so we don’t get that error? By making a POST request.

Fourth Task: POST Request

The following code snippet will allow you add more queries into your JSON Object:

@app.route('/favcat', methods=['POST'])
def add_cat():
    # @TODO: add a staff and their favorite cat 
    new_staff = request.get_json()
    fav_cats.append(new_staff)
    return jsonify({'new staff': new_staff})

However, since this is a POST request, you need to navigate to Postman. Enter your workspace section and include http://127.0.0.1:24000/favcat/ as the URL. On the right, you should see a dropdown with different web requests. Click POST, then click Body -> Raw -> JSON in order to create a JSON entry. For our example, we will include Lou as as a staff and their favorite cat, like so:

{"name": "Lou", "breed": "All cats"}

Hit send, refresh the browser and you should see an entry of Lou’s favorite cat on the server. If it doesn’t show up, use CTRL + C in your terminal to kill the server and flask run to reboot it again, since sometimes Flask doesn’t always get updates to the server in a timely manner.

Fifth Task: PUT Request

PUT requests allow you to update an entry to your object

@app.route('/favecat/<string:name>', methods=['PUT'])
def edit_cat(name):
  update = request.get_json()
    for get_cat, get_staff in enumerate(fav_cats):
        if get_staff['name'] == name:
            fav_cats[get_cat] = update
    us = request.get_json()
    return jsonify({"list all cats": fav_cats})

Let’s say that Lou's favorite cat is a Tabby Cat instead of All Cats. Click PUT, then click Body -> Raw -> JSON and the URL handle is http://127.0.0.1:24000/favcat/Lou. Input the entry as {"name": "Lou", "breed" : "Tabby Cats"}. Hit run and we can see that Lou’s favorite cat breed is a Tabby Cat!

Sixth Task: DELETE Request

The following code snippet will allow you to delete an entry of your JSON Object:

@app.route('/favcat/<string:name>', methods=['DELETE'])
def delete_cat(name):
    # @TODO: delete a staff and their favorite cat:(
    return_cat = fav_cats[0]
    for get_cat, get_staff in enumerate(fav_cats):
        if get_staff['name'] == name:
            del fav_cats[get_cat]
    return jsonify({'Here is our database now ': fav_cats})

Just like our POST Request, we want to be able to delete an entry through Postman. The process is the same, except you have to navigate to the specific NAME you created to delete the entry on Postman. So say you wanted to delete Lou, you would have to go to http://127.0.0.1:24000/favcat/Lou to delete them.

Seeing Your Requests on Postman

Insert your target URL on Postman.

This tutorial will help you navigate through Postman with managing your requests. This is good for trying things out and developing iteratively. You can even create automated tests for your API through Postman.

Learn more

Ethics

Ideas

  • Could you build an API to return information about some dataset or service?
  • How can you combine this with a database like PostgreSQL/Mongo DB?

Requirements

  • You should show it off in your README.md file, with animations/video and an explanation of the backend. Make sure to include installation instructions.
  • Has to use a Open Source license via a LICENSE file.