Creating APIs with Flask and testing in Postman
Tags: postman, python, programming, api
Published: 2023-08-03 14:20:22

The role of APIs (application programming interface) in the tech industry is crucial to all aspects of the SDLC (software development lifecycle), from backend building APIs, frontend developers using it to create applications, and even testers ensuring it works before shipping to users. All these professionals play a pivotal role in enabling different systems, applications, and services to communicate and interact with each other seamlessly.

In this article, you will learn how to build an API using the Python framework, Flask and ultimately test it in Postman.


## Source code

Find the complete source code for this project in this [GitHub repository](https://github.com/Terieyenike/apis-flask). Fork and clone the repo.


## Prerequisites

Ensure you meet the following requirements to follow through this post:

- Have Python 3 installed on your local machine
- Understanding of the basic of Python
- Download the [Postman app](https://www.postman.com/downloads/) for your OS (operating system)


## What is Postman

Postman is a collaboration and API development tool that allows developers to create, share, design, test, and document the process of building APIs.


## Activating a virtual environment

Before we write a line of code, creating a virtual environment is necessary when setting up a new Flask application. From the Python official documentation, a **virtual environment** is created on top of an existing Python installation, a self-contained directory with its packages and dependencies containing the specific version for the application to ensure consistency across different environments.

To create a virtual environment, use the Python built-in `venv` module with this command:

In macOS and Linux, use:

    python3 -m venv <name-of-project>
    
    // for example
    python3 -m venv flask-apis

Windows

    python -m venv <name-of-project>

Replace the `<name-of-project>` with your desired project name. The command above will create a new directory where the virtual environment will reside.

The folder should look like this:


    .
    └── flask-apis
        ├── bin
        ├── include
        └── pyvenv.cfg

Next, navigate to the project directory to activate the virtual environment. 

To be sure you are referencing the right shell, check out [this guide](https://docs.python.org/3/library/venv.html#how-venvs-work) for the command based on your shell.

macOS - bash/zsh

    source ./bin/activate

After activation, your command prompt will show the name of the environment, indicating that you are working within it.


    (flask-apis) (base)  ✝  ~/Desktop/flask-apis 


## Installing Flask

Within the activated environment, run this command to install Flask:


    pip install flask

Let’s confirm the installation of the flask package with this command:


    pip show flask


![flask package detail](https://paper-attachments.dropboxusercontent.com/s_5A2134138C9C71134A5D143BF1EDD5E70CAF44FD8435A7637DFF73282E298723_1691059358878_image.png)



## Creating APIs using Flask

The first thing to do in every new project is to create a new file containing the application code. 

Run this command to create a new file within the project folder:


    touch app.py 

Copy-paste this code:

`app.py`
```python
    from flask import Flask, request
    
    app = Flask(__name__)
    
    model = []
    
    @app.get('/friend')
    def get_friends():
      return model
    
    @app.get('/friend/<int:id>')
    def get_one_friend(id):
      return model[id], 200
    
    @app.post('/friend')
    def create_friend():
        request_data = request.get_json()
        new_friend = {"name": request_data["name"], "id": len(model)}
        model.append(new_friend)
        return new_friend, 201
    
    @app.delete('/friend/<int:id>')
    def delete_friend(id):
      del model[id]
      return {"success": "data successfully deleted from the server"}, 200
```

In this code snippet, the Flask web framework creates APIs with its endpoints and the HTTP methods (GET, POST, DELETE).

Here’s the breakdown of each line:

- `from flask import Flask, request`: Import the Flask and request classes from the flask module. The `Flask` class is vital in handling the application instance,  while the request object is responsible for accepting incoming request data, query parameters, and JSON payloads
- `app = Flask(__name__)`: this line creates the new Flask application instance named app. The `__name__` refers to the name of the current Python module
- `module = []` assigns an empty list used to store the friend list items
- `@app.get` this HTTP route decorator listens for GET requests on the endpoint or path defined in the bracket **()**
- `@app.get('/friend/<int:id>')` returns the list of an individual item as a response using the HTTP GET route path parameter with an **OK** response message of **200**
- The function like the **def get_friends()** is responsible for displaying the incoming GET requests as a response
- The **model** displays the store items in an array or list
- `@app.post` is the HTTP route decorator that sends POST requests to a specified path in the server
- The `request.get_json()` method extracts the JSON sent in the POST request, and the following line creates a new dictionary with the **id** sets to the length of the model, which increment on every new data sent
- The **new_friend** is added to the **model** list representing the collection of friends and returns a status code, 201 (**created**), to indicate that the POST request is successful and a new resource created
- The **delete** route, like the name, deletes a dictionary from the list with the id specified on the path

Let’s run this application to get the development server URL with the command:


    flask --app app --debug run

`app`: is the name of the file that contains the application code. If you named the file `hello.py`, you must replace `app` with `hello`.

The web application will run on `http://127.0.0.1:5000/`.


    Serving Flask app 'app'
     * Debug mode: on
    WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
     * Running on http://127.0.0.1:5000
    Press CTRL+C to quit
     * Restarting with stat
     * Debugger is active!
     * Debugger PIN: 100-724-825


## Testing in Postman

Open your Postman app to test the API. 

In the Postman app, you can create Collections to hold all your request within a Workspace. Check out [this article](https://dev.to/terieyenike/how-to-use-postman-for-api-testing-10cl) to learn how to create a workspace.

Let’s use the **POST** method for the first request to create a new friend object. In the request section of the window, click the **Body** tab and set the data type to JSON by checking the **raw** button. Click the **Send** button for the response with the status code **201 CREATED**.


![post a friend](https://paper-attachments.dropboxusercontent.com/s_5A2134138C9C71134A5D143BF1EDD5E70CAF44FD8435A7637DFF73282E298723_1691064769975_image.png)


You can create as many **friends** as possible with the **id** increasing by 1 on each new request sent.

Set the endpoint **/friend** with the GET method as shown:


![get friends](https://paper-attachments.dropboxusercontent.com/s_5A2134138C9C71134A5D143BF1EDD5E70CAF44FD8435A7637DFF73282E298723_1691065370647_image.png)


The response list all the **friends’** object in an array.

**Get an individual friend**
To see the result of a friend, use the id from the friend object with the endpoint /friend just like this: 


    http://127.0.0.1:5000/friend/2


![get a friend](https://paper-attachments.dropboxusercontent.com/s_5A2134138C9C71134A5D143BF1EDD5E70CAF44FD8435A7637DFF73282E298723_1691065568531_image.png)


**Deleting a friend**
Every application created should be able to remove an item from the list, which is the same when done in Postman.

Select the **DELETE** method and the endpoint with the id like this:


![delete a friend](https://paper-attachments.dropboxusercontent.com/s_5A2134138C9C71134A5D143BF1EDD5E70CAF44FD8435A7637DFF73282E298723_1691065905038_image.png)


The success message indicates the removal of the item from the database. To confirm the deletion of the item from the endpoint **/friend/0**, use the GET HTTP method to see the new list of friends.

```json
    [
        {
            "id": 1,
            "name": "teri"
        },
        {
            "id": 2,
            "name": "eloho"
        }
    ]
```

As an extra practice lesson, let’s create a website form and send its data using Postman instead of interacting with the client's UI (user interface), a browser. 

Still, in the application folder, create a new file, `forms.py`, and copy-paste this code:

`forms.py`
```python
    from flask import Flask, request
    
    app = Flask(__name__)
    
    student = []
    
    @app.get("/api/v1.0/students")
    def students():
      return student
    
    @app.post("/api/v1.0/students")
    def create_student():
      name = request.form['name']
      country = request.form['country']
      city = request.form['city']
      skills = request.form['skills'].split(', ')
      bio = request.form['bio']
      birthyear = request.form['birthyear']
      details = {
        'name': name,
        'country': country,
        'city': city,
        'birthyear': birthyear,
        'skills': skills,
        'bio': bio,
      }
      student.append(details)
      return details
```

Now run this application to start the development server:


    flask --app forms --debug run

It is the same principle as explained earlier, but this time instead of using the raw data type, select the `form-data` type. Form data enables you to send key-value pairs and specify the content type.


![form data](https://paper-attachments.dropboxusercontent.com/s_5A2134138C9C71134A5D143BF1EDD5E70CAF44FD8435A7637DFF73282E298723_1691067432740_image.png)


For this request, they are all the **Text** content type, and to access the form data sent in the POST request, we use **request.form,** a dictionary-like object containing the data submitted through the form.

The response to its data should look something like this:


![response form data](https://paper-attachments.dropboxusercontent.com/s_5A2134138C9C71134A5D143BF1EDD5E70CAF44FD8435A7637DFF73282E298723_1691067879681_image.png)



## Conclusion

Postman is a tool every developer should have in their arsenal, as it is more than creating APIs. It is capable of so much more. 

As seen in this post, Flask as a Python framework helped us create a robust and scalable API architecture rather than relying on Node.js as an alternative option for all our development work. Explore this framework today! 

This article is an overview of the possibilities of Flask and using Postman to test your endpoints to ensure it works before deployment, as it shows you errors by writing test cases for your requests.


## Resources

[Creating a minimal application in Flask](https://flask.palletsprojects.com/en/2.3.x/quickstart/)
[Postman documentation](https://learning.postman.com/docs/publishing-your-api/documenting-your-api/)
[Creation of virtual environments](https://docs.python.org/3/library/venv.html)
[Writing tests in Postman](https://learning.postman.com/docs/writing-scripts/test-scripts/)