This project is a machine learning microservice that predicts bike rentals using a CatBoost regression model. The service is built with FastAPI and serves as an example of how to deploy an ML model as an API. Please inspect this notebook to learn more about the underlying problem we are trying to solve and the ML model that makes the inferences in this API.
The project demonstrates the integration of several modern tools and frameworks, including:
- FastAPI: For building the RESTful API.
- CatBoost: For inference and running the predictive ML model.
- Docker: For containerization and deployment.
Please check this article to learn how to build an application like this.
- Prediction Endpoint: Exposes a
/predictendpoint to predict bike rentals based on input features such as season, temperature, and weather conditions. - Scalability: The project is containerized using Docker, making it easy to deploy and scale.
- Extensibility: Can be extended to include new features or models.
ml_model_api/
├── .github/
│ └── workflows/
│ └── main.yml # GitHub Actions workflow for CI/CD
├── app/
│ ├── models/
│ │ └── bike_sharing.py # Pydantic models for input validation
│ ├── services/ # Services
│ │ └── ml_model.py # Tools for handling saved predictive models
│ └── main.py # Main FastAPI application
├── communication/ # Contains the code to generate the tutorial article (Quarto)
├── data/
│ ├── features_api_test_data.csv # CSV file for testing API inputs
│ └── target_api_test_data.csv # CSV file for testing API outputs
├── docs/ # Tutorial article (web page)
├── notebooks/
│ └── eda_and_toy_model.ipynb # Exploratory data analysis and model experimentation
├── predictive_models/
│ └── catboost_model_19Dec2024.cbm # CatBoost model file
├── tests/
│ ├── requests_examples.sh # Example API requests
│ ├── test_api.py # Integration tests for API endpoints
│ ├── test_inference.py # Tests for ML model inference
│ └── test_unit.py # Unit tests for core components
├── venv/ # Virtual environment for Python dependencies
├── .gitignore # Git ignore rules
├── Dockerfile # Dockerfile for containerization
├── LICENSE # Project license
├── README.md # Project documentation
├── memory_refresher.sh # So I don't forget things
└── requirements.txt # Python dependencies
- Python 3.12 or higher
- virtualenv (recommended)
- Docker (for containerization)
- Linux (I used Ubuntu 24.04)
The easiest way to use this application is by pulling and running the pre-built Docker image from Docker Hub. Follow these steps:
Run the following command to download the image:
docker pull jospablo777/ml-model-api:latestStart the container with the following command:
docker run -d -p 8000:80 --name bike-sharing-api jospablo777/ml-model-api:latestThe API will be accessible at:
- Base URL: http://localhost:8000
- Swagger UI: http://localhost:8000/docs
- ReDoc: http://localhost:8000/redoc
You can now send requests to the API, such as POST requests to /predict for bike rental predictions.
git clone https://github.com/jospablo777/ml_model_api.git
cd ml_model_apiInstall the dependencies in your virtual environment once you're in the project's folder.
python -m venv venv # Create a virtual environment called venv
source venv/bin/activate # Activate the environment
pip install -r requirements.txt # Setup the environment with the required librariesRun the API locally using uvicorn:
uvicorn app.main:app --reload --host 127.0.0.1 --port 8000- API Root: http://127.0.0.1:8000/
- Swagger UI (API Documentation): http://127.0.0.1:8000/docs
- ReDoc (Alternative Documentation): http://127.0.0.1:8000/redoc
If you want to continue with the process and build the docker image yourself, continue with these steps after exiting the app with Ctrl+C.
docker build -t bike-rental-prediction-api .docker run -d -p 8000:80 --name bike-rental-prediction-api bike-rental-prediction-api- API Root: http://127.0.0.1:8000/
- Swagger UI (API Documentation): http://127.0.0.1:8000/docs
- ReDoc (Alternative Documentation): http://127.0.0.1:8000/redoc
Make a POST request to /predict with the following input format:
[
{
"season": "Summer",
"mnth": "June",
"hr": 14,
"holiday": "No",
"weekday": "Monday",
"workingday": "Yes",
"weathersit": 1,
"temp": 0.78,
"atemp": 0.697,
"hum": 0.43,
"windspeed": 0.2537
}
]{
"predictions": [123.45]
}curl -X POST "http://127.0.0.1:8000/predict" -H "Content-Type: application/json" -d '[
{
"season": "Summer",
"mnth": "June",
"hr": 14,
"holiday": "No",
"weekday": "Monday",
"workingday": "Yes",
"weathersit": 1,
"temp": 0.78,
"atemp": 0.697,
"hum": 0.43,
"windspeed": 0.2537
},
{
"season": "Summer",
"mnth": "June",
"hr": 9,
"holiday": "No",
"weekday": "Tuesday",
"workingday": "Yes",
"weathersit": 2,
"temp": 0.65,
"atemp": 0.62,
"hum": 0.55,
"windspeed": 0.19
},
{
"season": "Summer",
"mnth": "June",
"hr": 19,
"holiday": "No",
"weekday": "Wednesday",
"workingday": "Yes",
"weathersit": 1,
"temp": 0.85,
"atemp": 0.78,
"hum": 0.4,
"windspeed": 0.21
}
]'No need to cite, but it would mean a lot if you did! 😃 Feel free to use this code and project structure in your personal or work projects—make it yours!
Let's keep in touch!
- LinkedIn: José Pablo Barrantes
- BlueSky: doggofan77.bsky.social