How to create a REST API with Python

As a MuleSoft architect, having a lightweight non-mule REST API for testing is essential when working with 
Flex Gateway, demos, and integration scenarios. Instead of relying on third-party services, building a simple Python-based API gives us full control over the responses, endpoints, and behavior needed for our use case. 

In this post, I'll walk you through setting up a "Hello World" REST API using Flask, running it in a Docker container, and making it accessible for testing. Whether you're validating request routing, security policies, or API governance with Flex Gateway, this quick and easy setup will provide a solid foundation for our testing needs.

Prerequisites

To follow this example, we’ll use a virtual machine (VM) running Ubuntu Server 24.04 LTS with Docker installed. This setup ensures a controlled environment for testing and makes it easy to containerize and deploy the REST API. Check out this post to know How to Install Docker on Ubuntu Server.

We'll also need Python 3 and pip to install Flask but we'll see how to do it next.


Install Python and Flask

First we install Python

sudo apt-get update
sudo apt-get install python3 python3-pip -y

After that we install Flask (Flask is a lightweight Python web framework used to build APIs and web applications quickly. It is very flexible, and does not require complex configurations, making it ideal for small projects)

pip3 install flask


Create the API

Create a new Python script, for example app.py. Open the file with a text editor (we’ll use nano in here, but you could use vi or any other)

nano app.py

Add the following code to the file:

from flask import Flask

app = Flask(__name__)

@app.route('/hello', methods=['GET'])
def hello_world():
return {"message": "Hello World from Python!"}, 200

if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)

Where:

  • from flask import Flask This imports Flask
  • app = Flask(__name__) - This creates a Flask application instance
  • @app.route('/hello', methods=['GET']) - is a route decorator that maps the /hello URL to a function.
  • methods=['GET'] ensures that this route only responds to HTTP GET requests.
  • def hello_world() - Defines the function that runs when someone accesses /hello.
  • return - Returns a JSON response
    • {"message": "Hello World from Python!"} is returned as a JSON response.
    • The second value, 200, is the HTTP status code (200 means "OK").
  • if name == 'main' - This checks if the script is being run directly (not imported as a module) and ensures that the application starts only when you run python app.py directly.
  • app.run() starts the Flask web server.
  • host='0.0.0.0' - This allows the API to be accessible from any IP address, not just localhost.
  • port=5000 - This makes the API listen on port 5000.


Run the API

Run the script:

python3 app.py

With that, our API will be running on port 5000


We can run it in the background as well using nohup:

nohup python3 app.py &

For a production deployment, though, we should set it up as a systemd service.


Test the API

To test it, we can use our web browser and navigate to http://localhost:5000/hello. Alternatively we can use Postman or curl

curl http://localhost:5000/hello

In response, we should see the message:

{"message": "Hello World from Python!"}


Create Dockerfile

Once we’ve got our Python REST API working, it’s always a great idea to containerize it. For that, let’s use Docker and see how we can create the Docker image for our REST API. Images in Docker are built from Dockerfiles. 

From the same directory of our REST API, create a file called Dockerfile and paste the following content

# Use an official Python runtime as a parent image
FROM python:3.9-slim

# Set the working directory
WORKDIR /app

# Copy the current directory contents into the container at /app
COPY . /app

# Install dependencies
RUN pip install flask

# Make port 5000 available to the world outside this container
EXPOSE 5000

# Define the command to run the application
CMD ["python", "app.py"]


Build the Docker Image

Now, create the image from our Dockerfile running the following command:

docker build -t hello-python-api .

where 
hello-python-api is the name of the image.


Run the Docker container

Let’s test our image by running a container from it with the command:

docker run -d -p 5000:5000 hello-python-api

Where:

  • -d: Run the container in detached mode.
  • -p 5000:5000: Map port 5000 of the host to port 5000 of the container.


Test the API in the container

Test the API running in the container by accessing it through localhost or the server's IP. As earlier, we can use our web browser, Postman or curl:

curl http://localhost:5000/hello

And the response should be same

{"message": "Hello World from Python!"}


Push the Image to Docker Hub

Lastly, let’s make our image available in Docker Hub so that we can download it from any machine. For that, we need to follow these steps:
First, login to our Docker Hub account

docker login -u [YOUR_DOCKERHUB_USERNAME]

Tag the image for Docker Hub

docker tag hello-python-api [YOUR_DOCKERHUB_USERNAME]/hello-python-api

Last step, push the image to Docker Hub:

docker push [YOUR_DOCKERHUB_USERNAME]/hello-python-api

With that we can pull and run this image from any Docker host by running

docker run -d -p 5000:5000 [YOUR_DOCKERHUB_USERNAME]/hello-python-api

If you find the error "no matching manifest for linux/amd64 in the manifest list entries" that occurs when the Docker image you are trying to pull does not have a build compatible with your system's architecture(e.g., linux/amd64). That's probably because the image was built for a different architecture, most likely because the docker host where you build the image has a different architecture from the one you're trying to run the container. It happened to me when I built the image in my Mac and then try to deploy it on a Linux server.

Try rebuilding your image with multi-platform support:

docker buildx build --platform linux/amd64 -t [YOUR_DOCKERHUB_USERNAME]/hello-python-api:latest .
docker push [YOUR_DOCKERHUB_USERNAME]/hello-python-api:latest



Previous Post Next Post