Tutorial

How To Create a REST API with Flask on Ubuntu

Published on August 27, 2024

Sr Technical Writer

How To Create a REST API with Flask on Ubuntu

Introduction

In this tutorial, you will learn how to create a simple REST API using Flask, a lightweight Python web framework. We’ll cover the basics of setting up a Flask application, defining routes, handling requests, and returning JSON responses. By the end of this tutorial, you will have a working API that you can extend and integrate with other applications.

Prerequisites

  • A server running Ubuntu and a non-root user with sudo privileges and an active firewall. For guidance on how to set this up, please choose your distribution from this list and follow our initial server setup guide. Please ensure to work with a supported version of Ubuntu.

  • Familiarity with the Linux command line. For an introduction or refresher to the command line, you can visit this guide on Linux command line primer

  • A basic understanding of Python programming.

  • Python 3.7 or higher installed on your Ubuntu system. To learn how to run a Python script on Ubuntu, you can refer to our tutorial on How to run a Python script on Ubuntu.

Step 1 — Setting Up Your Flask Environment

Ubuntu 24.04 ships Python 3 by default. Open the terminal and run the following command to double-check the Python 3 installation:

root@ubuntu:~# python3 --version
Python 3.12.3

If Python 3 is already installed on your machine, the above command will return the current version of Python 3 installation. In case it is not installed, you can run the following command and get the Python 3 installation:

root@ubuntu:~# sudo apt install python3

Next, you need to install the pip package installer on your system:

root@ubuntu:~# sudo apt install python3-pip

Once pip is installed, let’s install Flask.

You will install Flask via pip. It’s recommended to do this in a virtual environment to avoid conflicts with other packages on your system.

root@ubuntu:~# python3 -m venv myprojectenv
root@ubuntu:~# source myprojectenv/bin/activate
root@ubuntu:~# pip install Flask

Step 2 - Create a Flask Application

The next step is to write the Python code for the Flask application. To create a new script, navigate to your directory of choice:

root@ubuntu:~# cd ~/path-to-your-script-directory

When inside the directory, create a new Python file, app.py, and import Flask. Then, initialize a Flask application and create a basic route.

root@ubuntu:~# nano app.py

This will open up a blank text editor. Write your logic here or copy the following code:

app.py
from flask import Flask, jsonify, request

app = Flask(__name__)

@app.route('/')
def hello_world():
    return jsonify(message="Hello, World!")

# In-memory data store
items = [{"id": 1, "name": "This is item 1"}, {"id": 2, "name": "This is item 2"}]

Step 3 — Creating RESTful Routes

In this section, we’ll define routes in our Flask application that correspond to the different actions a user can perform on the API. Each route will handle a specific HTTP method.

GET, POST, PUT, and DELETE. These methods correspond to the four basic operations of persistent storage—often referred to as CRUD (Create, Read, Update, Delete).

Add the following routes to your app.py python script:

app.py
from flask import Flask, jsonify, request

app = Flask(__name__)

@app.route('/')
def hello_world():
    return jsonify(message="Hello, World!")

# In-memory data store
items = [{"id": 1, "name": "This is item 1"}, {"id": 2, "name": "This is item 2"}]

# GET request: Retrieve all items
@app.route('/api/items', methods=['GET'])
def get_items():
    return jsonify(items)

# GET request: Retrieve a specific item by ID
@app.route('/api/items/<int:item_id>', methods=['GET'])
def get_item(item_id):
    item = next((item for item in items if item["id"] == item_id), None)
    if item is None:
        return jsonify({"error": "Item not found"}), 404
    return jsonify(item)

# POST request: Create a new item
@app.route('/api/items', methods=['POST'])
def create_item():
    new_item = {"id": len(items) + 1, "name": request.json.get('name')}
    items.append(new_item)
    return jsonify(new_item), 201

# PUT request: Update an existing item
@app.route('/api/items/<int:item_id>', methods=['PUT'])
def update_item(item_id):
    item = next((item for item in items if item["id"] == item_id), None)
    if item is None:
        return jsonify({"error": "Item not found"}), 404
    item['name'] = request.json.get('name', item['name'])
    return jsonify(item)

# DELETE request: Delete an item
@app.route('/api/items/<int:item_id>', methods=['DELETE'])
def delete_item(item_id):
    global items
    items = [item for item in items if item["id"] != item_id]
    return '', 204

if __name__ == "__main__":
    app.run(debug=True)

Let’s know more about what each function does:

  • Flask Imports: The code imports necessary components from Flask: Flask, jsonify, and request.

  • In-Memory Data Store: items is a simple list of dictionaries that acts as a temporary data store for the API. Each item has an id and a name.

  • GET /api/items: When a GET request is made to /api/items, the server returns a list of all items in the items data store. This is useful for retrieving all resources in a collection.

  • POST /api/items: A POST request to /api/items allows the client to create a new item. The server expects a JSON object containing the new item’s details in the request body. After creating the item, the server responds with the newly created item and a 201 Created status code.

  • PUT /api/items/<int:item_id>: A PUT request to /api/items/<item_id> is used to update an existing item with the specified item_id. The client sends the updated data in the request body, and the server modifies the existing item. If the item is not found, the server returns a 404 Not Found error.

  • DELETE /api/items/<int:item_id>: A DELETE request to /api/items/<item_id> removes the item with the specified item_id from the data store. If the item is successfully deleted, the server responds with a 204 No Content status code, indicating that the deletion was successful and there is no further content to return.

  • Running the Application: The if __name__ == "__main__": block ensures that the Flask application runs when the script is executed directly.

Step 4 — Running and Testing Your API

Start your Flask server using the following command:

root@ubuntu:~# python3 app.py

You should notice the Flask server running with the below output:

Output
* 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: 837-877-972

From the above output you can notice that the server is running on http://127.0.0.1 and listening on port 5000.

Now, you can test the endpoints using curl, Postman, or another HTTP client. In this tutorial you will use curl to test the endpoints and send the HTTP requests.

Open another Ubuntu Console and execute the below curl commands one by one:

  • GET: curl http://127.0.0.1:5000/api/items
  • POST: curl -X POST -H "Content-Type: application/json" -d '{"name": "This is item 3"}' http://127.0.0.1:5000/api/items
  • PUT: curl -X PUT -H "Content-Type: application/json" -d '{"name": "This is updated item 1"}' http://127.0.0.1:5000/api/items/1
  • DELETE: curl -X DELETE http://127.0.0.1:5000/api/items/1

Let’s see each of these commands in action:

root@ubuntu:~# curl http://127.0.0.1:5000/api/items
Output
[ { "id": 1, "name": "This is item 1" }, { "id": 2, "name": "This is item 2" } ]

You will notice that the server returns a list of all items in the items data store.

Using the POST method, let’s add a new item to the datastore.

root@ubuntu:~# curl -X POST -H "Content-Type: application/json" -d '{"name": "This is item 3"}' http://127.0.0.1:5000/api/items
Output
{ "id": 3, "name": "This is item 3" }

Note: On your other console where your Flask server is running, you will notice all the HTTP requests being executed and their respose codes too.

* Running on http://127.0.0.1:5000
Press CTRL+C to quit
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 837-877-972
127.0.0.1 - - [23/Aug/2024 06:57:27] "GET /api/items HTTP/1.1" 200 -
127.0.0.1 - - [23/Aug/2024 06:59:56] "POST /api/items HTTP/1.1" 201 -

This is a great way to monitor, debug, and troubleshoot any issues with the server.

Next, let’s execute a PUT request. A PUT request to /api/items/<item_id> will update an existing item with the specified item_id.

root@ubuntu:~# curl -X PUT -H "Content-Type: application/json" -d '{"name": "This is updated item 1"}' http://127.0.0.1:5000/api/items/1
Output
{ "id": 1, "name": "This is updated item 1" }

Now, let’s execute a GET request to see the updated item 1.

root@ubuntu:~# curl http://127.0.0.1:5000/api/items/1
Output
{ "id": 1, "name": "This is updated item 1" }

At last, let’s execute a DELETE request to delete an item from the datastore.

root@ubuntu:~# curl -X DELETE http://127.0.0.1:5000/api/items/1

This will delete item 1 from the data store.

To verify this, let’s execute a GET request.

root@ubuntu:~# curl http://127.0.0.1:5000/api/items
Output
[ { "id": 2, "name": "This is item 2" }, { "id": 3, "name": "This is item 3" } ]

You will notice that item 1 is no longer present and deleted permanently.

Conclusion

In this tutorial, you’ve built a basic REST API app using Flask. You can now extend this API with additional routes, integrate with a database, or deploy it to a cloud platform like DigitalOcean. Flask is a powerful tool for building APIs quickly and efficiently, and with these basics, you’re ready to start building more complex applications.

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about our products

About the authors
Default avatar

Sr Technical Writer

Sr. Technical Writer@ DigitalOcean | Medium Top Writers(AI & ChatGPT) | 2M+ monthly views & 34K Subscribers | Ex Cloud Consultant @ AMEX | Ex SRE(DevOps) @ NUTANIX

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
Leave a comment


This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Featured on Community

Get our biweekly newsletter

Sign up for Infrastructure as a Newsletter.

Hollie's Hub for Good

Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.

Become a contributor

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

Welcome to the developer cloud

DigitalOcean makes it simple to launch in the cloud and scale up as you grow — whether you're running one virtual machine or ten thousand.

Learn more