🚀 Introduction to the Series
Welcome to “The Observability Blueprint: Instrument, Deploy, Observe — OpenTelemetry in Action on Kubernetes” – where we take a humble machine learning application and give it superpowers: observability across metrics, logs, and traces using open-source tools like OpenTelemetry, Prometheus, Jaeger, Loki, and Grafana.
In this blog series, we’ll:
- 🤖 Build a simple ML app using FastAPI
- 📦 Instrument it using OpenTelemetry
- 🐳 Containerize it with Docker
- ☸️ Deploy it to Kubernetes
- 🔭 Collect and visualize observability data like a pro
🎯 Goal: show how to fully observe a production-ish ML app from every angle using only open-source tools.
Part 1: Building a Simple ML App with FastAPI
🧰 Prerequisites:
Before we start, make sure you have:
- Python 3.8+
pip
- Basic familiarity with Python and REST APIs (we promise to keep it friendly)
🔧 Step 0: Set Up a Virtual Environment
Let’s avoid polluting your global Python setup. Run the following:
python3 -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
pip3 install --upgrade pip
Create a requirements.txt
:
fastapi==0.110.0
pydantic==1.10.14
uvicorn==0.29.0
scikit-learn==1.4.2
numpy==1.26.4
Then Install:
pip3 install -r requirements.txt
🧠 Step 1: What’s Machine Learning? And Why Linear Regression?
Machine Learning is the art (and science) of teaching computers to learn patterns from data instead of writing rule-based code.
In this part, we’ll use Linear Regression, the "hello world" of ML models. It assumes there’s a straight-line relationship between input and output — in our case, the bigger the house, the higher the price. (Groundbreaking stuff, we know.)
Here’s the model training code:
# train_model.py
import numpy as np
import pickle
from sklearn.linear_model import LinearRegression
# Sample dataset: house sizes in sq ft and corresponding prices in dollars
# Data: [size (sq ft)], [price ($)]
X = np.array([[500], [1000], [1500], [2000], [2500]])
y = np.array([100000, 150000, 200000, 250000, 300000])
# Train the model
model = LinearRegression()
model.fit(X, y)
# Save the model to a file
with open("house_price_model.pkl", "wb") as f:
pickle.dump(model, f)
print("Model trained and saved as 'house_price_model.pkl'")
This generates a .pkl
file — a serialized version of our model we’ll later load inside an Application.
⚡ Step 2: Serve It via FastAPI
Let’s make it accessible to the outside world.
📦 Why FastAPI?
FastAPI is a modern Python web framework built for speed (thanks to Starlette & Pydantic), great dev experience, and automatic documentation. It’s a joy to use — kind of like Flask, but with type hints and Swagger included.
Let’s write our app:
# app.py
from fastapi import FastAPI, Request
from pydantic import BaseModel
import pickle
import numpy as np
# --------------------------
# FastAPI App Setup
# --------------------------
app = FastAPI()
# Load the model
with open("house_price_model.pkl", "rb") as f:
model = pickle.load(f)
# --------------------------
# Healthcheck endpoint
# --------------------------
@app.get("/")
def read_root(request: Request):
return {"message": "House Price Prediction API is live!"}
# --------------------------
# Define the request schema
# --------------------------
class HouseFeatures(BaseModel):
features: list[float]
# --------------------------
# Prediction endpoint
# --------------------------
@app.post("/predict/")
def predict(data: HouseFeatures, request: Request):
prediction = model.predict(np.array(data.features).reshape(1, -1))
logger.info(f"Prediction made: {prediction[0]}")
return {"predicted_price": prediction[0]}
▶️ Run it with:
uvicorn app:app --reload
🧪 Try It Out
curl -i 'http://127.0.0.1:8000/'
POST to /predict/
with:
curl -i -X POST 'http://127.0.0.1:8000/predict/' -H "Content-Type: application/json" -d '{"features": [1500]}'
💡 Output:
{
"predicted_price": 200000.0
}
Congratulations, you just served your first ML model! 🎉
✅ What’s Next?
In Part 2, we’ll dockerize the app so it's ready for deployment in the wild. We’ll also start thinking about instrumenting the app — because what’s an API without observability metrics to brag about?
{
"author" : "Kartik Dudeja",
"email" : "[email protected]",
"linkedin" : "https://linkedin.com/in/kartik-dudeja",
"github" : "https://github.com/Kartikdudeja"
}
Top comments (0)