Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.
Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.
Pedro Martinho
Tiago Franco

Min Read

April 15, 2025

How to Build a Flask API with Python: The Complete Guide

Laptop screen showing lines of code

What is Flask and Why Use it for APIs?

Flask is a lightweight Python web framework ideal for building RESTful APIs and microservices. Unlike heavier frameworks like Django, Flask is minimal and unopinionated, giving developers full control over application structure. This flexibility makes it an excellent choice for developing custom, scalable web APIs tailored to specific project requirements.

So, Flask Python is a microframework that will allow you to have a web application running with very few steps and nearly no setup. This framework's simplicity and strong control over what you want in your application have made it one of the most used web development frameworks.

Python is a very popular and powerful language with a big community that has been around for a long time. Many great companies, such as Google, use it for their projects, and the number of people using it for web development is still increasing.

We will show you it is simple, flexible, and modular, leading to an enjoyable development experience.

We expect the user to have some basic knowledge of Python to understand all the presented steps. Nevertheless, any person should be able to have the application up and running after following this tutorial.

blue arrow to the left
Imaginary Cloud logo

What is Flask Python?

A framework is a library used by developers to build and maintain reliable and scalable web applications. There are several frameworks available for Python, such as Tornado, Pyramind, and of course, Django (which is often compared with Flask).

Flask(🌶️) is a Python microframework for web development. Despite being built with a small core and considered a very lightweight Web Server Gateway Interface (WSGI), Flask stands out for its easy-to-extend philosophy. It was designed to scale up to complex applications and to support an easy and quick start.

Moreover, another great advantage of Flask is its functionality. Even though it offers suggestions, Flask does not mandatorily require project layouts or other dependencies. Instead, it allows developers to choose the libraries and tools they wish to use and additionally has various extensions available, that are provided by the community.

blue arrow to the left
Imaginary Cloud logo

What is a REST API?

API is an acronym of Application Programming Interface, which means it is basically how you communicate with an application. A REST (Representational State Transfer) API allows communication between systems using standard HTTP methods and corresponds to an architectural style that aims for stateless communications and separates client and server concerns. It typically exchanges data in JSON format and operates using endpoints that correspond to actions like Create (POST), Read (GET), Update (PUT or PATCH), and Delete (DELETE). REST APIs are widely used for their simplicity, scalability, and compatibility with a broad range of clients and platforms.

The REST API on this exercise will create a fake implementation of CRUD actions over an entity. An API with CRUD allows the Create, Read, Update and Delete operations over the application's elements.

How to make a REST API using Python Flask?

This article will guide you through the first steps to create a REST API using Flask(🌶️).

Below you can see the endpoints you’ll have by the end of the tutorial. The documentation presented is also generated by the application you will create!

Swagger documentation for Flask API showing PUT and GET endpoints with example payload and parameters.
Screenshot of Flask endpoint documentation

Technical requirements

You must have Python installed on the current machine. The code presented will consider Python3. If you want to use Python2 and/or are following this procedure in a Windows machine, please follow the instructions presented in the Flask installation guide.

Let’s start by creating a directory to store the project. In the directory you want to have your project, run the following commands on the shell:

We’ve created the flask_demo directory and moved it inside. Before starting to install dependencies, let’s create a virtual environment by running the following command:

This will create a folder into your project with the name .venv. After that, we need to activate the respective environment by running:

This means we are now considering the venv virtual environment when running any Python code. It might be important to specify the environment you are considering when running it in your IDE.

Make sure you have the environment active before following the next steps. You can check if you are inside the environment by looking to the left side of the console. If there’s the virtual environment name inside parentheses, you’re good to go.

If you want to deactivate the environment, just run the following command:

Screenshot of Flask - venv virtual command environment.

Setting Up Your Flask API Development Environment

Before you begin developing a Flask API, ensure you have Python installed. It's recommended to use a virtual environment to manage dependencies and keep your project isolated.

Install the Flask package using pip (Python package installer):

pip install Flask==2.3.3

At the point of writing, the Flask stable version is 2.3.3. If you want to have the project specifications updated and aligned with this version, you can use a requirements.txt file instead of installing Flask manually. You can copy the file below to the root directory:

Flask==2.3.3

After that, you just need to run the following command:

pip install -r requirements.txt

Now we are ready to start developing our REST API.

Hello World

The first endpoint code:

### First Steps: Your Hello World Flask API
Here’s how to build your first minimal Flask REST API:

```python
from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello():
    return {'message': 'Hello, World!'}

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

This example sets up a basic endpoint that returns a JSON response. The app.run() function launches a development server that listens on port 5000 by default.


What?! Is it that simple? Yes, it is! The code is done to have an application with an implemented endpoint. Now we simply have to define the Flask environment variables and see your application ?. Note that you need to be in the folder with the main.py file to run this commands.

Access the link http://localhost:5000/basic_api/hello_world to see the classic message we all love.

REST API with CRUD structure

Now that we have created our first endpoint, let’s get back to this application blog post's main purpose: Have the REST API with the basic CRUD structure. Let’s build an API that supports CRUD operations on a list of items. This is a common use case in web development and backend services.

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

items = []

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

@app.route('/items', methods=['POST'])
def add_item():
    data = request.get_json()
    items.append(data)
    return jsonify(data), 201

@app.route('/items/<int:index>', methods=['PUT'])
def update_item(index):
    data = request.get_json()
    items[index] = data
    return jsonify(data)

@app.route('/items/<int:index>', methods=['DELETE'])
def delete_item(index):
    item = items.pop(index)
    return jsonify(item)

This simple REST API in Flask allows clients to manage a list of items using standard HTTP methods.


Now, for each of the routes created different methods are allowed. The following endpoints are available:

  • GET /entities - get list of entities
  • POST / entities - create an entity
  • GET / entities/<entity_id> - get entity information
  • PUT / entities/<entity_id> - update entity
  • DELETE / entities/<entity_id> - delete entity

With this structure, you are ready to create an API with all the complexity you need. This is not the most scalable structure since you consider multiple validations for each route, and the structure is not rigid. In the next sections, we’ll cover a more scalable solution that allows easy documentation creation as you develop your endpoints.

Another tool that is very useful and common to use in the development of APIs is Postman. If you’ve never used it, we recommend you try it and explore it! It is very powerful and will increase your development to the moon and beyond. 🚀

Blueprints

Before we present other Flask strengths, let’s talk about blueprints. A blueprint is an object very similar to a Flask application object, but instead of creating a new one, it allows the extension of the current application. This might be useful if you want to create multiple versions of an API or simply divide services within the same application.

We will use this class type to present different use case scenarios of a Flask application. Let’s convert the code above to be inserted into a blueprint and loaded into the main application.

Create a new folder named blueprints to start inserting blueprint modules as we progress in the blog post. Inside it, create a folder named basic_endpoints and then a file named __init__.py:

# blueprints/basic_endpoints/__init__.py
from flask import Blueprint, jsonify

basic_bp = Blueprint('basic_bp', __name__)

@basic_bp.route('/')
def hello():
    return jsonify({'message': 'Hello from a Blueprint!'})

Now the main.py file just needs to load the created blueprint and register it to the application object:

# main.py
from flask import Flask
from blueprints.basic_endpoints import basic_bp

app = Flask(__name__)
app.register_blueprint(basic_bp)

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

Now you should have exactly the same endpoints but using the structure provided by Blueprints. This will make your application easier to manage and scale as it grows.

Jinja Templates for Flask

As already stated, Flask is a very minimal framework; however, it relies on a handy tool: the Jinja template engine. This allows for rendering dynamic HTML templates. Although this is out of this blog post's scope, we will just give a small example to demonstrate the concept.

The first thing you have to do is create the templates folder and inside this folder, insert the example.html file.


Note there are two variables in use in the template inside {{ }}. This is a special format to include Python code inside the template, allowing for dynamic content to be rendered. In this case, we have the top and bottom of the variable, which will be converted to text inside the <p> tag. Now that the template is created let’s load it using Flask. Let’s create a new blueprint in a different file to demonstrate this example:

<!-- templates/example.html -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Jinja Template Example</title>
</head>
<body>
    <p>{{ top }}</p>
    <p>{{ bottom }}</p>
</body>
</html>

Note there are two variables in use in the template inside {{ }}. This is a special format to include Python code inside the template, allowing for dynamic content to be rendered. In this case, we have the top and bottom of the variable, which will be converted to text inside the <p> tag. Now that the template is created let’s load it using Flask. Let’s create a new blueprint in a different file to demonstrate this example:

# blueprints/jinja_demo/__init__.py
from flask import Blueprint, render_template, request

jinja_bp = Blueprint('jinja_bp', __name__)

@jinja_bp.route('/jinja_template')
def jinja_example():
    top = request.args.get('top', 'Default Top Text')
    bottom = request.args.get('bottom', 'Default Bottom Text')
    return render_template('example.html', top=top, bottom=bottom)

Do not forget to register this blueprint in the main.py file:

# main.py
from flask import Flask
from blueprints.jinja_demo import jinja_bp

app = Flask(__name__)
app.register_blueprint(jinja_bp)

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


Here we can see the definition of the top and bottom variables based on the query params sent in the URL. For example, if you go to http://localhost:5000/jinja_template?top=top_text&bottom=bottom_text you will get the following result:

Screenshot of result of the top and bottom variables.

Adding CSS

For the giggles, let’s add some CSS to the page we just created. Create the static folder with the file example.css inside.

/* static/example.css */
body {
    font-family: Arial, sans-serif;
    text-align: center;
    background-color: #f9f9f9;
    margin-top: 50px;
}

p {
    font-size: 24px;
    font-weight: bold;
    color: #333;
}


After that, add the corresponding reference to the CSS file we just created by adding this head tag to the HTML file:

<!-- templates/example.html -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Jinja Template Example</title>
    <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='example.css') }}">
</head>
<body>
    <p>{{ top }}</p>
    <p>{{ bottom }}</p>
</body>
</html>


Go to http://localhost:5000/jinja_template?top=cancel%20the%20REST%20API%20creation&bottom=I%20have%20to%20watch%20this%20bird and you should see something like this:

Screenshot of a meme showing a black cat with a yellow necktie with the message "Cancel the Rest API creation, I have to watch this bird" indicating an error.

There! You have your jinja crash course and a meme generator endpoint! Do not touch the Business Cat! You might be surprised with what you'll find...

Digital Transformation Service CTA
blue arrow to the left
Imaginary Cloud logo

How to create a swagger documentation with Flask?

Now that we’ve considered some basic functionalities to have basic endpoints created with Flask, let’s create a better project structure for our endpoints.

Comic showing Swagger as the preferred way to document a REST API with Flask.

Everyone knows the guy is right, but it can be a boring process. Fear not! With the use of the Flask extension Flask-RESTPlus we can have documentation generated automatically and with a better structure if you follow their recommendations on scalable projects.

To have it installed, just like flask, run the following command:

pip install flask-restplus

If you want to have the same flask-restplus version as the point of writing, just add

flask-restplus==0.13.0

to the requirements.txt file and install the requirements again. There are some problems related to dependencies, therefore, you have also to install the version 0.16.1 from the Werkzeug package by running:

pip install Werkzeug==0.16.1

Let’s now take a look to the project structure we have so far and the one we propose for this blueprint we are creating:

Project structure showing Flask blueprints and templates for API modularisation.

For the documented endpoints, let’s create a folder to identify the entity we are working on. This will facilitate the navigation through the project as it gets bigger and increasingly more complex. Each of the folders inside the documented_endpoints works like modules with the functionalities/endpoints related to that entity (in this case, users and cats).

We’ll present all the endpoints already created with a new structure. The endpoints will have no logic but will allow you to understand the steps involved in their creation.

With that said, let’s move on to the code. First, we should consider the hello_world endpoint with the new structure:

# blueprints/documented_endpoints/hello_world.py
from flask_restplus import Namespace, Resource, fields

hello_ns = Namespace('hello_world', description='Hello World operations')

hello_model = hello_ns.model('HelloWorld', {
    'message': fields.String(required=True, description='A hello world message')
})

@hello_ns.route('/')
class HelloWorld(Resource):
    @hello_ns.response(200, 'Success', hello_model)
    @hello_ns.response(500, 'Internal Server Error')
    def get(self):
        '''Returns a Hello World message'''
        return {'message': 'Hello, World!'}, 200


Now let’s break it down. One of the first things that you might notice is the usage of the Namespace and Resource classes. The Namespace is directly linked to a specific entity, meaning that all the hello_world endpoints will be linked to the corresponding namespace. This will generate the hello_world section in the swagger documentation.

To create routes in this Namespace, different classes that inherit from the Resource class are declared along with the respective namespace route decorator. Within the created HelloWorld class we declare the methods it contemplates. In our case, only GET is presented, resulting in a GET method available for the docummented_endpoints/hello_world endpoint.

The hello_world related models are presented and will be linked to the respective endpoint. This generates the documentation for the endpoint response and marshal the respective response.

The comments associated with the created resources and respective methods will generate descriptions on the final documentation. The possible errors the endpoint can return should also be specified as presented in the example and will also result in further endpoints documentation. There are more functionalities supported by the flask-restplus extension, such as parsers and error handling. Please refer to their documentation if you want to take full advantage of its capabilities.

Now let’s present the code to link this Namespace we have created to a blueprint (blueprints/documented_endpoints/__init__.py) and after that link the blueprint to the application (main.py):

# blueprints/documented_endpoints/__init__.py
from flask import Blueprint
from flask_restplus import Api
from .hello_world import hello_ns

blueprint = Blueprint('documented_api', __name__, url_prefix='/documented_api')
api = Api(blueprint, doc='/doc', title='Documented API', description='Auto-generated Swagger Docs with Flask-RESTPlus')

api.add_namespace(hello_ns)


Here, an API object from fask-restplus module is created and linked to the documented_api blueprint. The link between the blueprint and the hello_world namespace we have created is done with this object with the add_namespace method. Finally, just like all the previous blueprints, we just have to register the created blueprint to the app object. Follow the link http://localhost:5000/documented_api/doc and you'll get this page:

Flask Rest plus Demo to present the code for the documentation so any person can check all the endpoints.

Now let’s present the code for the documentation of the entities REST API and jinja template page so any person can easily check all the endpoints we’ve been working on. This is done by adding the following files:


Even though these files might look scary, the logic is the same as the one presented for the hello world endpoint. The main difference is the usage of models to generate documentation and validate the request body sent in POST and PUT methods. Parsers are also used for the query params documentation and can also be used for validation. This is useful for scenarios in which the data is not sent via body, such as query params or FormData.

Last but not least, do not forget to add the following lines to have the created namespaces linked to the Blueprint we are creating.

Bellow, you can check the documentation appearance for query params and a request body:

Swagger parameter documentation for Flask API with query and body payload using JSON.

Now we have the documentation of all the endpoints and the respective endpoints (of course!!).

blue arrow to the left
Imaginary Cloud logo

Conclusion

Despite its simplicity, Flask is an extremely powerful Python web framework. It is much easier and more straightforward than creating complete server-side applications. Plus, it can save you so much time!

Hopefully, by the end of this article, you will have no trouble creating a REST API using Flask and automatically generating a swagger documentation page. Additionally, you should be familiar with specific functions (such as Blueprint objects) and setting up Jinja templates.

blue arrow to the left
Imaginary Cloud logo

blue arrow to the left
Imaginary Cloud logo
blue arrow to the left
Imaginary Cloud logo
blue arrow to the left
Imaginary Cloud logo
blue arrow to the left
Imaginary Cloud logo
blue arrow to the left
Imaginary Cloud logo

Frequently asked questions

What is a Flask API?

A Flask API refers to a RESTful web service built using the Flask framework in Python. It exposes endpoints that clients can interact with over HTTP, typically returning data in JSON format.

Is Flask a backend API?

Yes, Flask can be used as a backend framework to build APIs that serve data to frontend applications or third-party services.

What is the difference between Flask and REST?

Flask is a web framework, while REST is an architectural style for designing networked applications. You can use Flask to implement REST APIs.

Is Python Flask good for API?

Yes, Flask is an excellent choice for building APIs due to its simplicity, flexibility, and a wide range of extensions that support documentation, authentication, and deployment.

What are some common use cases for Flask?

Flask is commonly used for building REST APIs, microservices, admin dashboards, prototyping applications, and integrating with machine learning models.

Build scalable products with Web and Mobile Development call to action

Found this article useful? You might like these ones too!

Pedro Martinho
Pedro Martinho

Associate developer working mostly with Backend technologies. An entrepreneur with Data Science interest. Love for sports, audiobooks, coffee and memes!

Read more posts by this author
Tiago Franco
Tiago Franco

CEO @ Imaginary Cloud and co-author of the Product Design Process book. I enjoy food, wine, and Krav Maga (not necessarily in this order).

Read more posts by this author

People who read this post, also found these interesting:

arrow left
arrow to the right
Dropdown caret icon