Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 52

Deploy Scikit-learn Models with FastAPI

Recommended resources

Welcome back! In our previous lessons, you mastered the art of diagnosing model weaknesses through systematic error analysis and learned how to translate those insights into targeted improvements. You now have a robust, well-understood model. But a model sitting in a Jupyter Notebook isn't creating value yet. It's time to take it out of the lab and into the world.

This lesson marks your first step into MLOps and deployment. You will learn how to build a simple REST API to wrap your trained scikit-learn model using FastAPI. This makes your model accessible to other applications—be it a web front-end, a mobile app, or another backend service—allowing them to send data and receive predictions over the network.

Given your experience with web frameworks like Django and Flask, you'll find many concepts here familiar. We'll be defining routes and handling requests, but with a focus on the specific needs of serving a machine learning model.

What is a Model-Serving API?

At its core, an API (Application Programming Interface) is a set of rules that allows different software applications to communicate with each other. A REST API is a popular type that uses standard HTTP requests (like GET, POST, etc.) to manage resources.

When we "deploy" a model as a REST API, we are essentially creating a web server that:

  1. Listens for incoming HTTP requests containing new data.
  2. Processes that data using our trained model to generate a prediction.
  3. Sends the prediction back as an HTTP response, typically in a structured format like JSON.

FastAPI is a modern, high-performance Python web framework designed specifically for building APIs. It's incredibly fast, easy to learn, and comes with two killer features we'll use today:

  • Automatic data validation using Pydantic, which prevents bad data from ever reaching your model.
  • Interactive API documentation (Swagger UI), which creates a user-friendly web interface for testing your API right out of the box.
This diagram shows a typical ML workflow. This lesson focuses on the "Deployment" stage, where we take a trained model and wrap it in a service using FastAPI so it can start making predictions on production data.

Let's get started.


1. The Core Workflow: Train, Save, and Serve

The process of creating a model API involves three main steps. A great tutorial that walks through this entire process is "Build a Machine Learning API Using FastAPI & Scikit-Learn" from the Data Science with Onur channel. We'll follow its structure.

Build a Machine Learning API Using FastAPI & Scikit-Learn (Step-by-Step Python Tutorial)

This first part of the video demonstrates the foundational step: training a simple model and serializing it for later use.

Watch the section on training and saving the model. The narrator trains a basic LinearRegression model and saves it using Python's pickle library.

The key idea here is serialization: converting our trained model object into a byte stream that can be saved to a file. This file can then be loaded by a separate application—our API—without needing to retrain the model.

While pickle works perfectly well, it's common in the scikit-learn ecosystem to use joblib. joblib is more efficient for objects that carry large NumPy arrays, which is often the case with scikit-learn estimators. The process is nearly identical:




# With pickle
import pickle
with open('model.pkl', 'wb') as f:
    pickle.dump(model, f)




# With joblib
import joblib
joblib.dump(model, 'model.joblib')

For this lesson, either is fine. The important part is that you have a saved model file ready for the next step.


2. Building the API with FastAPI

Now, let's build the API itself. We'll create a new Python file, let's call it main.py, and build our service piece by piece.

The article "The Machine Learning Practitioner's Guide to Model Deployment with FastAPI" provides an excellent, clear text-based walkthrough of these same steps.

The Machine Learning Practitioner's Guide to Model ...

This guide clearly breaks down the three essential components of our FastAPI application.

Read Step 2: Creating a FastAPI App, Step 3: Defining What Input Your Model Expects, and Step 4: Creating the Prediction Endpoint. Pay close attention to how Pydantic is used to define the HouseInput class and how the @app.post("/predict") decorator connects a URL to our prediction function.

Let's solidify those concepts from the video and article.

Step 2.1: Initialize the App and Load the Model

Every FastAPI application starts by creating an instance of the FastAPI class. Immediately after, you should load your serialized model into memory.




# main.py
from fastapi import FastAPI
import joblib # Or pickle




# Create the FastAPI app instance
app = FastAPI(title="ML Model API")




# Load the trained model from the file
model = joblib.load("house_price_model.joblib")

By loading the model at startup, it's kept in memory and ready to serve predictions instantly. This is far more efficient than loading the model from disk for every single request.

Step 2.2: Define the Input Schema with Pydantic

How do we tell our API what the incoming data should look like? This is where Pydantic comes in. We define a class that inherits from BaseModel and declare our expected input features as class attributes with type hints.

from pydantic import BaseModel




# Define the structure of a single data point for prediction
class PredictionInput(BaseModel):
    size_square_feet: float
    bedrooms: int

FastAPI uses this class to do four things automatically:

  1. Read the body of a POST request as JSON.
  2. Validate that the JSON contains size_square_feet and bedrooms.
  3. Validate that the values have the correct types (a float and an int).
  4. Generate the "Schema" you see in the automatic API documentation.

This provides a strong contract for your API and prevents malformed data from crashing your model.

Step 2.3: Create the Prediction Endpoint

An endpoint is a specific URL in your API that performs an action. We'll create a /predict endpoint that accepts POST requests. In FastAPI, we use a function decorator to link a function to an endpoint.

import numpy as np




# Define the prediction endpoint
@app.post("/predict")
def predict(data: PredictionInput):



    # 1. Extract data in the correct order
    features = np.array([[data.size_square_feet, data.bedrooms]])
    



    # 2. Make a prediction
    prediction = model.predict(features)
    



    # 3. Return the result
    return {"predicted_price": prediction[0]}

Let's break down the predict function signature: def predict(data: PredictionInput):.
By type-hinting the data parameter with our Pydantic class PredictionInput, FastAPI automatically parses the incoming request body and validates it against that schema. If validation passes, the request data is available in the data object.


3. Running and Testing Your API

Your API code is written, but it's just a Python script. To bring it to life, you need a server. Uvicorn is the standard server for running FastAPI applications.

First, you'll need to install FastAPI and Uvicorn:
pip install "fastapi[all]"

Now, you can run your API from the terminal in the same directory as your main.py file.

uvicorn main:app --reload
  • main: The Python file main.py.
  • app: The FastAPI object created inside main.py (app = FastAPI()).
  • --reload: A development flag that automatically restarts the server whenever you save changes to your code.

Once you run this command, you'll see output indicating the server is running, usually on http://127.0.0.1:8000.

Now for the best part. Open your web browser and navigate to http://127.0.0.1:8000/docs.

You will see an interactive API documentation page generated by Swagger UI.

An example of the interactive Swagger UI documentation that FastAPI generates automatically. It provides a clean interface to view and test all of your API's endpoints.

This interface allows you to test your /predict endpoint directly from your browser. The video below shows exactly how to do this.

Build a Machine Learning API Using FastAPI & Scikit-Learn (Step-by-Step Python Tutorial)

This part of the video shows how to launch the Uvicorn server and use the Swagger UI to perform a test prediction.

Watch the short sections on running the server and accessing the docs. Then, see how a test is performed using the interactive interface by watching from the prediction test.


Your Turn: Putting It All Together

Now it's your chance to build a simple API.

  1. Create a virtual environment and install the necessary packages: fastapi, uvicorn, scikit-learn, numpy, and joblib.
  2. Train and save a model. You can use the simple linear regression example from the video or any other scikit-learn model you've worked with. Save the trained model to a .joblib or .pkl file.
  3. Write your main.py file. Follow the steps outlined above:
    • Import necessary libraries (FastAPI, Pydantic, joblib/pickle, numpy).
    • Create your FastAPI app instance.
    • Load your saved model.
    • Define a Pydantic BaseModel for your model's input features.
    • Create a @app.post("/predict") endpoint.
    • Inside the endpoint function, process the input data, make a prediction, and return it.
  4. Run your API using uvicorn main:app --reload.
  5. Test it by going to http://127.0.0.1:8000/docs, expanding the POST endpoint, clicking "Try it out," and filling in some sample data.

Conclusion

Congratulations! You've successfully taken a trained machine learning model and exposed its predictive power through a robust, validated REST API. You've bridged the gap between data science in a notebook and a functional service that can be integrated into larger systems.

Key Takeaways:

  • Serialization (with pickle or joblib) is the process of saving a trained model to a file.
  • FastAPI is a modern Python framework for building APIs. It is run using a server like Uvicorn.
  • Pydantic models are used to define a strict schema for your API's input data, providing automatic validation.
  • Decorators (@app.post()) are used to define API endpoints and link them to Python functions.
  • FastAPI automatically generates interactive Swagger UI documentation at the /docs URL, which is invaluable for testing and sharing your API.

The Swagger UI is excellent for manual testing, but in a real-world workflow, you'd test your API programmatically. In our next lesson, we will do just that by writing a Python script with the requests library to send data to our new API and verify its responses.