Skip to content

Example Python Bottle Containerized API


Python


Python API Description


This is an example of how to build a simple python API built into a docker container.


Python API Code


The following code snippit sets up a bottle server that runs a very simple api. The api is set to recieve a GET type request, and just builds a simple response, returning back a user name, team name, and the version of the API, along with a simple message. To use the example code below, simply copy the contents of the code block into a file named example_api.py and save it.


# *******************************************************************
# Bottle Example API
# Authors/Maintainers: Rich Nason (rnason@appcontainers.com)
# *******************************************************************

# Required Modules:
# =================

# Install Requrirements via PIP
from bottle import Bottle, HTTPResponse  # Webserver
import os  # Used to access Environment Variables

# Bottle Parameters:
# ===================

VERSION = '0.0.1'     # API Version
BOTTLEIP = '0.0.0.0'  # The IP that Bottle will listen on to serve the API
BOTTLEPORT = '8500'   # The TCP port that bottle will use to serve the API


# Setup the Bottle WebServer Instance:
# ====================================

APP = Bottle(__name__)


# Index Route
@APP.route('/', method=['OPTIONS', 'GET'])
def index():
    try:
        # team_id = '0'
        team_id = os.environ['TEAM_ID']
        user_id = os.environ['USER_ID']
        resp_msg = "All systems reporting go for launch!!"
        body = {
            'version': VERSION,
            'message': resp_msg,
            'team_id': team_id,
            'user_id': user_id
        }

        response = HTTPResponse(status=200, body=body)
        return response
    except Exception as err:
        print(err)
        body = {'version': VERSION, 'message': err}
        response = HTTPResponse(status=400, body=body)
        return response


# Start the Web Server
# =====================

if __name__ == '__main__':
    try:
        SERVER = APP.run(host=BOTTLEIP, port=BOTTLEPORT, debug=True)
    except KeyboardInterrupt:
        pass
        print('exiting...')
        SERVER.stop()


Python API Dockerfile


The following dockerfile example will take the example_api.py that we saved and package it into an alpine linux container image. To use the following example Dockerfile, copy the code block below and save it to a file named Dockerfile in the SAME directory where you saved example_api.py.


############################################################
# Dockerfile to build an example API endpoint
# Based on: alpine:latest
# DATE: 09/28/2017
# COPYRIGHT: Appcontainers.com
############################################################

# Set the base image
FROM alpine:latest

# File Author / Maintainer
MAINTAINER "Rich Nason" <rnason@appcontainers.com>

###################################################################
#***************  OVERRIDE ENABLED ENV VARIABLES  *****************
###################################################################

ENV TEAM_ID 0
ENV USER_ID "aws"

###################################################################
#*******************  UPDATES & PRE-REQS  *************************
###################################################################

# Install dependancies
RUN apk update && apk add curl python py-pip jq vim && \
pip install bottle

###################################################################
#*******************  APPLICATION INSTALL  ************************
###################################################################

ADD example_api.py /media/api.py

###################################################################
#*****************  CONFIGURE START ITEMS  ************************
###################################################################


###################################################################
#******************  ADD REQUIRED APP FILES  **********************
###################################################################

ADD example_api.py /root/api.py

###################################################################
#*************  CMD & EXPOSE APPLICATION PORTS  *******************
###################################################################

CMD [ "sh", "-c", "python /root/api.py" ]

EXPOSE 8500

Build the Docker image


Now that we have the code sample, and the dockerfile, we can now build the docker image. In order to build the docker image, perform the following command.


Docker Build Command:

docker build -t lab/api:latest .

Command Console Output:

.... lots of previous build steps ....
Removing intermediate container 81685f9ffa39
 ---> 50c6a144e0d9
Step 6/9 : ADD example_api.py /media/api.py
 ---> 2171293f12df
Step 7/9 : ADD example_api.py /root/api.py
 ---> 631b3e19cb9b
Step 8/9 : CMD [ "sh", "-c", "python /root/api.py" ]
 ---> Running in 1ae34ac04982
Removing intermediate container 1ae34ac04982
 ---> 0137b26bdfcc
Step 9/9 : EXPOSE 8500
 ---> Running in a43eef49415e
Removing intermediate container a43eef49415e
 ---> 0f3f317eb27c
Successfully built 0f3f317eb27c
Successfully tagged lab/api:latest


Launch the Docker Image


At this stage we should have a docker image created, and ready to be launched. Verify that the image was created successfully using the docker images command, and then we are ready to launch the container and test it. Use the following commmand syntax in order to run the container image.


Check the Image Syntax:

docker images

Command Console Output:

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
lab/api             latest              c1fb6fb0da32        6 minutes ago       79.3MB
alpine              latest              76da55c8019d        2 weeks ago         3.97MB


Command to Launch the Container:

docker run -it -d --name api -h api -p 8500:8500 -e TEAM_ID=1 -e USER_ID="Dr Who" lab/api:latest

Command Console Output:

fd7ebb3fc0ebab790e8fb140f1aa8f3227a7927ffd9540d0e4b61b1b96bc499f


Docker Run Statement:

The Docker run statement has the -d flag which tells the container to run as a deamon process. As such only the container ID was returned. To see additional details about the container use the docker ps --all command. Additonally below you will find a brief description of what each of the above flags specified in the Docker run statement do.

  • -it - Run the container interactively with a TTY
  • -d - Run the container in daemon mode
  • --name - Set the name of the container
  • -h - Set the hostname of the container
  • -p - Publish port, in this example it will bind the host port of 8500 to the container port of 8500
  • -e - Pass environment variable into the container runtime


Testing the Container


Once the docker run statement has beeen executed, the contianer should now be up and running. In order to test it you can simply send a standard GET request to the API using either a standard browser or Postman. You should recieve a JSON response in the following format.

1.    Check the Container Run State:
The first thing we will want to do to test the running container is to check the containers run state to ensure that the container is properly up and running and that host ports are bound to the exposed container ports. We can do this using the docker ps --all command.


Docker Process List Command:

docker ps --all

Command Console Output:

CONTAINER ID        IMAGE                          COMMAND                  CREATED             STATUS                    PORTS                    NAMES
fd7ebb3fc0eb        lab/api:latest                 "sh -c 'python /root…"   9 minutes ago       Up 9 minutes              0.0.0.0:8500->8500/tcp   api


Looking at the command output, we can see that the STATUS of the container is Up and the container has the host (My Workstation) listening on port 8500, and its forwarding requests to that port to the exposed container port 8500. Next lets fire up a GET request to test the container runtime. For this simple example we can simply use the Curl utility to perform the GET request.


Curl GET Request:

curl http://127.0.0.1:8500

Curl Response:

{
    "message": "All systems reporting go for launch!!",
    "version": "0.0.1",
    "user_id": "Dr Who",
    "team_id": "1"
}


Python API Additional Resources


Below you will find the direct download links to the python script and the Dockerfile:


Download Python Example API


example_api.py


Download Python Example API Dockerfile


Dockerfile


Python API Site/Information References


No Addtional References


Comments