Lab Manual
Containerize the REST API
application using Docker.
Disclaimer: The content
Disclaimer: is curated
The content from from online/offline resources and used for educational purpose only
is curated
online/offline resources and used for educational
purpose only
Containerize the REST API application using Docker
Objective
To containerize a Python-based Flask REST API application that serves a trained Iris classifier model
using Docker, enabling consistent deployment across different environments.
Pre-requisites
Basic knowledge of Python programming.
Familiarity with Flask for creating REST APIs.
Understanding of machine learning concepts.
Basic understanding of Docker concepts, such as images, containers, and Dockerfiles, and
familiarity with Docker commands.
Knowledge of Git for version control to manage the project files.
Requirements
A computer preferable windows 11.
Python 3.12.
Docker Desktop installed and running.
Git installed.
A code editor (e.g., VS Code).
Installed Python libraries: like scikit-learn, flask, requests, joblib, pytest
Procedure
Step 1: Set Up the Project Structure
This step involves creating a project directory and organizing files to support the Flask application and
Docker configuration.
1. Open your terminal or command prompt.
2. Create a new directory named iris-classifier-docker to hold all project files:
mkdir iris-classifier-docker
3. Navigate into the directory:
cd iris-classifier-docker
4. Initialize a Git repository to track changes:
git init
5. Create the following project structure using your code editor or terminal commands (e.g., touch
[Link] for files):
Disclaimer: The content is curated from online/offline resources and used for educational purpose only
iris-classifier-docker/
|--- [Link] # Flask application to serve the API
|--- train_model.py # Script to train and save the model
|--- test_app.py # Unit tests for the API
|--- [Link] # List of Python dependencies
|--- Dockerfile # Docker configuration file
|---.gitignore # File to specify files/folders to ignore in
Git
6. Create a .gitignore file to exclude temporary files and cached data. Open .gitignore in your code
editor and add:
# .gitignore
__pycache__/
*.pyc
venv/
.env
Note: The iris_model.pkl file will be included in Git as it’s required for the application.
Step 2: Train and Save the Iris Classifier Model
This step trains a Random Forest Classifier on the Iris dataset and saves the model for use in the Flask
API.
1. Open your code editor and create a new file named train_model.py in the project directory.
2. Add the following code to train_model.py. This script loads the Iris dataset, splits it into training
and testing sets, trains a Random Forest Classifier, and saves the model using joblib:
# train_model.py
from [Link] import load_iris
from sklearn.model_selection import train_test_split
from [Link] import RandomForestClassifier
import joblib
# Load the Iris dataset, which includes 150 samples with 4 features each
iris = load_iris()
X, y = [Link], [Link] # X: features (sepal/petal measurements), y:
target (0=setosa, 1=versicolor, 2=virginica)
# Split the dataset into 80% training and 20% testing sets, using a fixed random
seed for reproducibility
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2,
random_state=42)
# Initialize a Random Forest Classifier with 100 decision trees for robust
predictions
clf = RandomForestClassifier(n_estimators=100, random_state=42)
# Train the classifier on the training data
[Link](X_train, y_train)
# Save the trained model to a file named 'iris_model.pkl' for later use
[Link](clf, "iris_model.pkl")
3. Save the file.
Disclaimer: The content is curated from online/offline resources and used for educational purpose only
4. In the terminal, ensure you’re in the project directory and run the script:
python train_model.py
5. Verify the terminal output shows: "Model saved as iris_model.pkl".
6. Check that the iris_model.pkl file is created in the project directory using your file explorer or by
running ls (Unix-like systems) or dir (Windows).
7. Add the iris_model.pkl file to Git, as it’s needed by the Flask app:
git add iris_model.pkl
Step 3: Create the Flask REST API
This step builds a Flask web server to serve the trained model via RESTful endpoints, allowing external
systems to make predictions.
1. Open your code editor and create a new file named [Link] in the project directory.
2. Add the following code to [Link]. This script sets up a Flask server, loads the saved model, and
defines endpoints for a home page and predictions:
Disclaimer: The content is curated from online/offline resources and used for educational purpose only
# [Link]
from flask import Flask, request, jsonify
import joblib
import numpy as np
# Load the trained model from the saved file
model = [Link]("iris_model.pkl")
# Initialize the Flask application
app = Flask(__name__)
@[Link]("/")
def home():
return "Iris Classifier API is Running!" # Simple message to confirm server
status
@[Link]("/predict", methods=["POST"])
def predict():
try:
# Extract JSON data from the POST request
data = request.get_json(force=True)
# Validate input: ensure 'features' key exists and has exactly 4 values
if "features" not in data or len(data["features"]) != 4:
return jsonify({"error": "Exactly 4 numerical features are
required"}), 400
# Convert features to a NumPy array and reshape to (1, 4) for prediction
features = [Link](data["features"], dtype=float).reshape(1, -1)
# Make prediction using the loaded model
prediction = [Link](features)[0]
# Map numerical prediction to species name
classes = ["setosa", "versicolor", "virginica"]
result = {"prediction": classes[prediction]}
# Return prediction as JSON
return jsonify(result)
except Exception as e:
# Handle errors (e.g., invalid data types) and return error message
return jsonify({"error": str(e)}), 400
if __name__ == "__main__":
[Link](host="[Link]", port=5000) # Run on all interfaces for Docker
3. Save the file.
4. Ensure iris_model.pkl is in the same directory as [Link].
5. Test the Flask app locally:
python [Link]
6. Open a browser and visit [Link] You should see "Iris Classifier API is Running!".
7. Stop the server with Ctrl+C.
Disclaimer: The content is curated from online/offline resources and used for educational purpose only
Step 4: Create Unit Tests
Unit tests ensure the API works as expected. This step uses pytest to test the endpoints.
1. Open your code editor and create a new file named test_app.py in the project directory.
2. Add the following code to test_app.py. This tests the home endpoint, a valid prediction, and an
invalid input:
# test_app.py
import pytest
from app import app
@[Link]
def client():
[Link]["TESTING"] = True
with app.test_client() as client:
yield client
def test_home_endpoint(client):
response = [Link]("/") # Test the home route
assert response.status_code == 200
assert b"Iris Classifier API is Running!" in [Link]
def test_predict_endpoint_valid_input(client):
response = [Link](
"/predict",
json={"features": [5.1, 3.5, 1.4, 0.2]} # Valid input for setosa
)
assert response.status_code == 200
assert [Link] == {"prediction": "setosa"}
def test_predict_endpoint_invalid_input(client):
response = [Link](
"/predict",
json={"features": [5.1, 3.5, 1.4]} # Invalid: missing one feature
)
assert response.status_code == 400
assert "error" in [Link]
3. Save the file.
4. Run tests locally:
pytest test_app.py
5. Verify all tests pass (e.g., "3 passed" in the terminal).
Step 5: Define Project Dependencies
List all required Python libraries in a [Link] file for Docker to install.
1. Create a new file named [Link] in the project directory.
2. Add the following content with exact versions for consistency:
Disclaimer: The content is curated from online/offline resources and used for educational purpose only
Flask==3.1.1
joblib==1.5.1
numpy==2.3.2
pandas==2.3.1
pytest==8.4.1
requests==2.32.4
scikit-learn==1.7.1
3. Save the file.
4. Install dependencies locally to ensure compatibility:
pip install -r [Link]
Step 6: Create the Dockerfile
This step defines a Dockerfile to containerize the Flask application, specifying the base image,
dependencies, and runtime configuration.
1. Open your code editor and create a new file named Dockerfile in the project directory (no file
extension).
2. Add the following content to Dockerfile. This uses a lightweight Python image, copies files,
installs dependencies, and sets the command to run the app:
# Dockerfile
FROM python:3.12-slim # Use a slim Python 3.9 image to reduce size
WORKDIR /app # Set the working directory inside the container
# Copy [Link] and install dependencies
COPY [Link] .
RUN pip install --no-cache-dir -r [Link]
# Copy all project files ([Link], iris_model.pkl, etc.)
COPY . .
# Expose port 5000 for the Flask app
EXPOSE 5000
# Command to run the Flask app
CMD ["python", "[Link]"]
3. Save the file.
4. The Dockerfile:
o Uses python:3.12-slim as the base image for efficiency.
o Sets /app as the working directory.
o Copies and installs dependencies from [Link].
o Copies all project files (including iris_model.pkl).
Disclaimer: The content is curated from online/offline resources and used for educational purpose only
o Exposes port 5000 for external access.
o Runs python [Link] to start the Flask server.
Step 7: Build and Test the Docker Container Locally
This step builds the Docker image and runs a container to test the application locally.
1. In the terminal, ensure you’re in the project directory (iris-classifier-docker).
2. Build the Docker image, naming it iris-classifier-api:
docker build -t iris-classifier-api .
o The -t flag tags the image as iris-classifier-api.
o The . specifies the current directory as the build context.
3. Verify the image was created:
docker images
You should see iris-classifier-api listed.
4. Run a container from the image, mapping port 5000 on the host to 5000 in the container:
docker run -p 5000:5000 iris-classifier-api
5. Open a browser and visit [Link] You should see "Iris Classifier API is Running!".
6. In a new terminal (while the container is running), test the /predict endpoint with cURL:
curl -X POST [Link] -H "Content-Type:
application/json" -d '{"features":[5.1, 3.5, 1.4, 0.2]}'
o Expected output: {"prediction":"setosa"}
7. Stop the container with Ctrl+C in the terminal running Docker.
Conclusion
In this lab, you accomplished the following:
Trained a Random Forest Classifier on the Iris dataset and saved it using joblib.
Built a Flask REST API to serve model predictions with input validation.
Created unit tests with pytest to ensure API reliability.
Defined project dependencies in [Link] for reproducibility.
Containerized the application using Docker, creating a portable image.
Tested the container locally and verified API functionality.
Disclaimer: The content is curated from online/offline resources and used for educational purpose only