REST API Dev: FastAPI & Flask for ML Integration

Learn REST API development with Python's FastAPI & Flask. Master ML model integration, understand concepts, and explore practical examples. Build powerful APIs.

REST API Development with FastAPI and Flask

This documentation provides an overview of REST API development using Python frameworks like Flask and FastAPI. It covers fundamental concepts, practical examples, feature comparisons, and common use cases, particularly for machine learning model integration.

1. What is a REST API?

REST (Representational State Transfer) is an architectural style that defines a set of constraints for creating web services. These services leverage the existing protocols of the World Wide Web, primarily HTTP.

A REST API (Application Programming Interface) allows different applications to interact over the web. It achieves this by enabling the sending and receiving of data, most commonly in the JSON (JavaScript Object Notation) format.

REST APIs are highly suitable for various applications, including:

  • Integrating Machine Learning (ML) models into applications.
  • Building mobile services.
  • Developing enterprise-level platforms.

Key Characteristics of REST:

  • Client-Server Architecture: A clear separation between the client (requesting data) and the server (providing data).
  • Statelessness: Each request from a client to a server must contain all the information necessary to understand and fulfill the request. The server should not store any client context between requests.
  • Cacheability: Responses can be cached on the client-side to improve performance.
  • Uniform Interface: A consistent way of interacting with resources, typically using HTTP methods.
  • Layered System: The client is unaware of whether it's directly connected to the end server or an intermediary.

2. What is Flask?

Overview

Flask is a micro web framework for Python. It is renowned for its lightweight nature and flexibility, making it an excellent choice for:

  • Rapid prototyping of APIs.
  • Developing small to medium-scale web applications.

Installation

To install Flask, you can use pip:

pip install flask

Simple Flask API Example

This example demonstrates a basic Flask API that accepts a list of numbers via a POST request and returns their sum.

from flask import Flask, request, jsonify

app = Flask(__name__)

@app.route('/predict', methods=['POST'])
def predict():
    """
    Accepts a JSON payload with a list of numbers and returns their sum.
    """
    try:
        data = request.get_json(force=True)
        input_data = data.get("input")
        if not isinstance(input_data, list):
            return jsonify({"error": "Input must be a list."}), 400
        
        # Perform a simple operation, e.g., sum the numbers
        result = sum(input_data)
        return jsonify({"prediction": result})
    except Exception as e:
        return jsonify({"error": str(e)}), 500

if __name__ == '__main__':
    # Run the Flask development server
    # host='0.0.0.0' makes the server accessible from any IP address
    app.run(host='0.0.0.0', port=5000)

Running the Flask Server

Save the code above as app.py and run it from your terminal:

python app.py

The API will be accessible at http://127.0.0.1:5000/predict.

3. What is FastAPI?

Overview

FastAPI is a modern, fast (high-performance) web framework for building APIs with Python 3.7+. It is built upon two powerful libraries:

  • Starlette: For the web handling part.
  • Pydantic: For data validation and serialization.

FastAPI's key advantages include:

  • Automatic Data Validation: Ensures that incoming data conforms to predefined structures.
  • Type Hinting: Leverages Python's type hints for code clarity and validation.
  • Interactive Documentation: Automatically generates interactive API documentation (Swagger UI and ReDoc) based on your code.

Installation

Install FastAPI and Uvicorn (an ASGI server required for FastAPI):

pip install fastapi uvicorn[standard]

Simple FastAPI Example

This example shows a FastAPI API that performs the same sum operation as the Flask example, using Pydantic for data validation.

from fastapi import FastAPI
from pydantic import BaseModel

# Define the request body structure using Pydantic
class InputData(BaseModel):
    input: list[float]

app = FastAPI()

@app.post('/predict')
def predict(data: InputData):
    """
    Accepts a JSON payload with a list of floats and returns their sum.
    Data validation is handled by Pydantic.
    """
    # FastAPI automatically validates 'data' against the InputData model
    result = sum(data.input)
    return {"prediction": result}

# Note: No explicit __main__ block needed for uvicorn execution

Running the FastAPI Server

Save the code above as main.py (or any other name) and run it using Uvicorn:

uvicorn main:app --host 0.0.0.0 --port 5000

The API will be accessible at http://127.0.0.1:5000/predict. You can also access the interactive API documentation at http://127.0.0.1:5000/docs (Swagger UI) or http://127.0.0.1:5000/redoc.

4. FastAPI vs. Flask: Feature Comparison

FeatureFlaskFastAPI
PerformanceModerateVery High (Leverages ASGI, async I/O)
Type CheckingManualBuilt-in (via Pydantic)
Data ValidationManual (or Flask extensions like Marshmallow)Automatic (via Pydantic)
Auto-generated DocsNoYes (Swagger UI, ReDoc)
Async SupportLimited (primarily synchronous)Native (supports async/await)
Learning CurveEasyModerate
Best Use CaseSimple APIs, quick prototypes, microservicesProduction APIs, ML serving, high-performance APIs

5. REST API Use Case: ML Model Integration

Deploying a trained machine learning model as a REST API is a common use case. Here's how you can do it with both Flask and FastAPI, assuming you have a pre-trained model saved as model.pkl.

Flask Example with Scikit-learn Model

import pickle
from flask import Flask, request, jsonify
import numpy as np # Often needed for model input

app = Flask(__name__)

# Load the pre-trained model
try:
    with open("model.pkl", "rb") as f:
        model = pickle.load(f)
except FileNotFoundError:
    model = None
    print("Error: model.pkl not found. Please ensure the model file is in the same directory.")

@app.route('/predict', methods=['POST'])
def predict():
    """
    Predicts using a loaded ML model. Accepts JSON with 'features'.
    """
    if model is None:
        return jsonify({"error": "Model not loaded."}), 503

    try:
        data = request.get_json()
        features = data.get('features')

        if features is None:
            return jsonify({"error": "Missing 'features' in request body."}), 400

        # Convert features to a format expected by the model (e.g., numpy array)
        # The exact format depends on how the model was trained.
        # For scikit-learn, it's often a 2D array-like structure.
        prediction = model.predict([features]) # Assuming features is a list, model expects a list of lists or 2D array

        # Return the prediction, converting numpy types if necessary
        return jsonify({'prediction': prediction.tolist()}) 

    except Exception as e:
        return jsonify({"error": str(e)}), 500

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

FastAPI Example with Scikit-learn Model

import pickle
from fastapi import FastAPI
from pydantic import BaseModel
import numpy as np # Often needed for model input

# Define the request body structure
class Features(BaseModel):
    features: list[float]

app = FastAPI()

# Load the pre-trained model
try:
    with open("model.pkl", "rb") as f:
        model = pickle.load(f)
except FileNotFoundError:
    model = None
    print("Error: model.pkl not found. Please ensure the model file is in the same directory.")

@app.post('/predict')
def predict(data: Features):
    """
    Predicts using a loaded ML model. Accepts Pydantic validated 'features'.
    """
    if model is None:
        return {"error": "Model not loaded."} # FastAPI typically returns JSON objects

    try:
        # 'data.features' is already validated by Pydantic
        # Convert features to a format expected by the model (e.g., numpy array)
        prediction = model.predict([data.features]) # Assuming data.features is a list

        # Return the prediction, converting numpy types if necessary
        return {"prediction": prediction.tolist()}

    except Exception as e:
        return {"error": str(e)}

# To run: uvicorn your_file_name:app --host 0.0.0.0 --port 5000

Conclusion

Both FastAPI and Flask are excellent choices for building REST APIs in Python.

  • Flask is praised for its simplicity and ease of use, making it ideal for rapid development, small projects, and quick prototypes.
  • FastAPI stands out with its high performance, built-in data validation, automatic documentation generation, and strong support for asynchronous operations. These features make it particularly well-suited for production-grade applications, especially those serving machine learning models at scale.

The choice between them often depends on the project's requirements regarding performance, scalability, and development speed.

SEO Keywords

  • REST API basics
  • Flask Python API
  • FastAPI framework
  • ML model deployment API
  • Flask vs FastAPI
  • Python API performance
  • API validation Python
  • Async API FastAPI
  • Swagger API docs
  • ML prediction API
  • Web services Python
  • HTTP methods API

Interview Questions

  • What is a REST API and why is it important in modern web development?
  • Which HTTP methods are most commonly used in REST APIs and what are their typical operations (e.g., GET, POST, PUT, DELETE)?
  • What is Flask and what are its typical use cases?
  • How do you create a basic API endpoint using Flask?
  • What are the main advantages of FastAPI over Flask?
  • How does FastAPI handle data validation automatically, and what library does it use for this?
  • What is Pydantic and how does it integrate with FastAPI to improve API development?
  • How do Flask and FastAPI differ in terms of asynchronous support, and why is it important?
  • How can you deploy a machine learning model using Flask or FastAPI?
  • What benefits do auto-generated API documentation tools like Swagger UI and ReDoc provide when using FastAPI?
  • Explain the concept of "statelessness" in RESTful architecture.
  • How would you handle error responses in a Flask or FastAPI API?