Example Python Bottle Containerized API
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
Download Python Example API Dockerfile
Python API Site/Information References
No Addtional References