Photo by the author Canva
If you like to build machine learning models and experiment with up-to-date things, it’s really chilly – but to be forthright, it becomes useful for others when you share them. For this purpose, you must serve it – reveal it via the Internet API, so that other programs (or people) can send data and recover forecasts. API REST appears here.
In this article, you will learn how we will go from a elementary machine learning model to the API -ready -made APi interface using Fastapi, one of the fastest and most internet framework programmers, in less than 10 minutes. And we will not stop at the demo version “Make It Run”, but we will add such things:
- Checking incoming data
- Registering each request
- Adding background tasks to avoid slowing down
- Grateful error service
Let us quickly show what our project structure will look like before we go to part of the code:
ml-api/
│
├── model/
│ └── train_model.py # Script to train and save the model
│ └── iris_model.pkl # Trained model file
│
├── app/
│ └── main.py # FastAPI app
│ └── schema.py # Input data schema using Pydantic
│
├── requirements.txt # All dependencies
└── README.md # Optional documentation
Step 1: Install what you need
We need several Python packages for this project: Fastapi for API, Scikit-Learn for the model and several helpers, such as Jablib and Pydantic. You can install them using PIP:
pip install fastapi uvicorn scikit-learn joblib pydantic
And save your environment:
pip freeze > requirements.txt
Step 2: Train and save a elementary model
Let’s keep part of the machine learning straight so that we can focus on using the model. We will employ the notable IRIS data set and train Random forest classifier To predict the type of iris flower based on its measures of petals and Sepal.
Here is a training script. Create a file called Train_model.py In model/ informant:
from sklearn.datasets import load_iris
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
import joblib, os
X, y = load_iris(return_X_y=True)
clf = RandomForestClassifier()
clf.fit(*train_test_split(X, y, test_size=0.2, random_state=42)[:2])
os.makedirs("model", exist_ok=True)
joblib.dump(clf, "model/iris_model.pkl")
print("✅ Model saved to model/iris_model.pkl")
This script charges data, divides it, trains the model and saves it using Joblib. Start once to generate the model file:
python model/train_model.py
Step 3: Define what input should expect the API interface
Now we need to define how users will interact with your API interface. What should they send and in what format?
We will employ pydantic, the built -in part of Fastapi to create a diagram describing and confirming incoming data. In particular, we will make sure that users provide four positive float values - for the length/width of the section and the length/width of the petals.
In a up-to-date file App/schema.pyto add:
from pydantic import BaseModel, Field
class IrisInput(BaseModel):
sepal_length: float = Field(..., gt=0, lt=10)
sepal_width: float = Field(..., gt=0, lt=10)
petal_length: float = Field(..., gt=0, lt=10)
petal_width: float = Field(..., gt=0, lt=10)
Here we added value restrictions (larger than 0 and less than 10) so that our input data is pure and realistic.
Step 4: Create API
Now it’s time to build a real API. We will employ Fastapi for:
- Load the model
- Accept JSON input data
- Predict the class and probability
- Log in a request in the background
- Return the pure answer Json
Let’s write the main API code inside app/main.py:
from fastapi import FastAPI, HTTPException, BackgroundTasks
from fastapi.responses import JSONResponse
from app.schema import IrisInput
import numpy as np, joblib, logging
# Load the model
model = joblib.load("model/iris_model.pkl")
# Set up logging
logging.basicConfig(filename="api.log", level=logging.INFO,
format="%(asctime)s - %(message)s")
# Create the FastAPI app
app = FastAPI()
@app.post("/predict")
def predict(input_data: IrisInput, background_tasks: BackgroundTasks):
try:
# Format the input as a NumPy array
data = np.array([[input_data.sepal_length,
input_data.sepal_width,
input_data.petal_length,
input_data.petal_width]])
# Run prediction
pred = model.predict(data)[0]
proba = model.predict_proba(data)[0]
species = ["setosa", "versicolor", "virginica"][pred]
# Log in the background so it doesn’t block response
background_tasks.add_task(log_request, input_data, species)
# Return prediction and probabilities
return {
"prediction": species,
"class_index": int(pred),
"probabilities": {
"setosa": float(proba[0]),
"versicolor": float(proba[1]),
"virginica": float(proba[2])
}
}
except Exception as e:
logging.exception("Prediction failed")
raise HTTPException(status_code=500, detail="Internal error")
# Background logging task
def log_request(data: IrisInput, prediction: str):
logging.info(f"Input: {data.dict()} | Prediction: {prediction}")
Let’s stop and understand what is going on here.
We load the model once after starting the application. When the user goes /provide The end point with the correct JSON input, we convert it to the NumPy board, go through the model and return the expected class and probability. If something goes wrong, we register it and return a cordial mistake.
Pay attention Task in the background Part – this is a shapely Fastapi function that allows us to work after sending a response (like saving dailies). This makes the API react and avoid delays.
Step 5: Start your API
To start the server, employ UVICORN Takus:
uvicorn app.main:app --reload
Visit: http://127.0.0.1:8000/docs
You will see the interactive Swagger interface where you can test the API interface.
Try this sample entrance:
{
"sepal_length": 6.1,
"sepal_width": 2.8,
"petal_length": 4.7,
"petal_width": 1.2
}
Or you can employ Curl to submit such a request:
curl -X POST "http://127.0.0.1:8000/predict" -H "Content-Type: application/json" -d
'{
"sepal_length": 6.1,
"sepal_width": 2.8,
"petal_length": 4.7,
"petal_width": 1.2
}'
Both of these generate the same answer, which is this:
{"prediction":"versicolor",
"class_index":1,
"probabilities": {
"setosa":0.0,
"versicolor":1.0,
"virginica":0.0 }
}
Optional step: implement your API
You can implement the Fastapi application for:
- Render.com (Implementing zero configuration)
- Railway.app (for continuous integration)
- Herok (via Docker)
You can also expand it to a service ready for production, adding authentication (such as Keys API or Oauth) to protect endpoints, monitoring demands using Prometheus and Grafana, and using Redis or celery for a queue in the background. You can also read my article: Step -by -step guide to implement machine learning models from Docker.
Wrapping
That’s all – and it’s better than most demos. What we built is more than an example of a toy. However, this is:
- Automatically verifies the input data
- Reflects significant answers of predictions
- Records each file request (API.LOG)
- Uses tasks in the background, so the API interface remains quick and responsive
- Copes gracefully failures
And all this in less than 100 code lines.
Canwal Mehreen Kanwal is a machine learning engineer and a technical writer with a deep passion for data learning and AI intersection with medicine. He is the co -author of the ebook “maximizing performance from chatgpt”. As a Google 2022 generation scholar for APAC, it tells diversity and academic perfection. It is also recognized as a variety of terradate at Tech Scholar, Mitacs Globalink Research Scholar and Harvard Wecode Scholar. Kanwalwal is a scorching supporter of changes, after establishing FemCodes to strengthen women in the STEM fields.
