Skip to content

KaranPatelDev/FastAPI-Capstone-Project

Repository files navigation

πŸš— Car Price Prediction – Full-Stack FastAPI + React

An end-to-end, production-style ML application that predicts car prices. It includes a FastAPI backend (JWT + API key security, Redis caching, Prometheus metrics), a modern React frontend (Vite + TypeScript + Tailwind + Framer Motion), containerization with Docker, and training code to (re)build the model.


πŸ“Œ TL;DR – Quick Start

Pick one path to run everything locally.

Option A) Docker Compose (full stack)

cd /d "D:\CODES\CampusX\FastAPI Capstone Project"
docker compose up --build

Option B) Local Dev (backend + frontend)

Backend (Windows CMD):

cd /d "D:\CODES\CampusX\FastAPI Capstone Project"
python -m venv .venv
".venv\Scripts\activate"
pip install -r requirements.txt
set REDIS_URL=redis://localhost:6379
uvicorn app.main:app --reload --port 8000

Frontend:

cd /d "D:\CODES\CampusX\FastAPI Capstone Project\frontend"
npm install
npm run dev

🧭 Table of Contents

  • Project Overview
  • Features
  • Architecture & Structure
  • Configuration
  • API Reference (Auth + Predict)
  • Frontend Highlights
  • Monitoring & Observability
  • Train or Retrain the Model
  • Run with Docker
  • Troubleshooting
  • Contributing & License

πŸ“ Project Overview

This project showcases how to ship an ML model as a secure, observable web service with a polished user experience:

  • High-performance FastAPI backend delivering predictions
  • JWT-based auth and API key guard on protected endpoints
  • Redis-backed caching (gracefully degrades if Redis is not available in dev)
  • Prometheus metrics out-of-the-box
  • React frontend with animations, validation, and local history
  • Production-ready Docker images and docker-compose orchestration

✨ Features

  • Auth: Login to obtain a JWT; send it via a token header (simple demo flow).
  • API Key: Gate prediction requests using api-key header.
  • Prediction: Car price estimates from a trained scikit-learn model.
  • Caching: Redis cache for repeated predictions.
  • Observability: Prometheus metrics and custom request logging middleware.
  • Frontend: Vite + React + TypeScript + Tailwind + Framer Motion + react-hook-form + zod + toast notifications.
  • Containers: API, Frontend (Nginx), Redis, Prometheus, Grafana.

πŸ—οΈ Architecture & Structure

High-level data flow:

Browser (React SPA)
   β”‚
   β–Ό
Vite/Nginx proxy  ──▢  FastAPI  ──▢  Model Service  ──▢  model.joblib
                           β”‚
                           └──▢  Redis Cache

Prometheus ◀───────────── FastAPI /metrics

Key folders:

  • app/ – FastAPI app
    • api/ – routes_auth.py (login), routes_predict.py (predict)
    • core/ – config.py (env), security.py (JWT), dependencies.py (headers)
    • services/ – model_service.py (load model, inference, caching)
    • cache/ – redis_cache.py (safe, optional cache client)
    • middleware/ – request logging
  • models/ – model.joblib (trained model)
  • training/ – train_model.py, train_utils.py (retrain pipeline)
  • data/ – car-details.csv
  • frontend/ – Vite + React app (multi-page, animated)

πŸ”§ Configuration

Environment variables (defaults in parentheses):

  • API_KEY (demo-key) – Required header: api-key
  • JWT_SECRET_KEY (secret) – Used for signing JWTs
  • REDIS_URL (redis://localhost:6379) – Redis connection; app tolerates absence in dev

Ports:

  • API: 8000
  • Frontend: 5173 (Nginx in Docker, Vite dev server in local dev)
  • Redis: 6379
  • Prometheus: 9090
  • Grafana: 3000

Security notes:

  • Auth uses a demo login (admin/admin) returning a JWT in access_token.
  • Protected endpoints expect two headers: token (JWT) and api-key.
  • CORS is set to allow all in dev; restrict origins before production.

πŸ“š API Reference

OpenAPI docs: http://localhost:8000/docs

1) Login (get JWT)

POST /login

Request

{ "username": "admin", "password": "admin" }

Success Response

{ "access_token": "<JWT>" }

Failure Response (demo behavior)

{ "error": "Invalid Credentials" }

2) Predict (protected)

POST /predict

Headers

  • token: <JWT>
  • api-key: demo-key (or your configured API_KEY)

Body (schema in routes_predict.py)

{
  "company": "Maruti",
  "year": 2015,
  "owner": "First Owner",
  "fuel": "Petrol",
  "seller_type": "Individual",
  "transmission": "Manual",
  "km_driven": 50000,
  "mileage_mpg": 18.0,
  "engine_cc": 1197,
  "max_power_bhp": 82,
  "torque_nm": 113,
  "seats": 5
}

Response

{ "predicted_price": "350,000.00" }

Example (PowerShell shown for readability; adapt to CMD as needed):

$token = (Invoke-RestMethod -Method Post -Uri http://localhost:8000/login -Body (@{username='admin';password='admin'} | ConvertTo-Json) -ContentType 'application/json').access_token
Invoke-RestMethod -Method Post -Uri http://localhost:8000/predict -Headers @{ token=$token; 'api-key'='demo-key' } -Body (@{
  company='Maruti'; year=2015; owner='First Owner'; fuel='Petrol'; seller_type='Individual'; transmission='Manual'; km_driven=50000; mileage_mpg=18; engine_cc=1197; max_power_bhp=82; torque_nm=113; seats=5
} | ConvertTo-Json) -ContentType 'application/json'

�️ Frontend Highlights

  • Built with Vite + React + TypeScript
  • TailwindCSS for styling, Framer Motion for subtle animations
  • React Router multi-page app: Home, Login, Predict, History, About, 404
  • Form validation: react-hook-form + zod
  • Toast notifications (react-hot-toast)
  • Local history persisted in localStorage

Dev proxy:

  • Vite proxies /api/* to http://localhost:8000/* during development
  • In production (Docker), Nginx proxies /api/* to the api service

Env vars (frontend):

  • VITE_API_URL – If set (e.g., http://localhost:8000/), Axios calls the API directly
  • VITE_API_KEY – If set, used as the api-key header (defaults to demo-key)

πŸ“ˆ Monitoring & Observability

  • Prometheus scrapes the API at /metrics (courtesy of prometheus-fastapi-instrumentator)
  • Grafana can visualize Prometheus metrics (compose includes Grafana)
  • Custom logging middleware logs requests and responses for traceability

Prometheus config lives in prometheus.yml.


πŸ§ͺ Train or Retrain the Model

  • Data: data/car-details.csv
  • Notebook: notebooks/sample.ipynb for exploration
  • Training: training/train_model.py produces app/models/model.joblib

Run training:

cd /d "D:\CODES\CampusX\FastAPI Capstone Project"
".venv\Scripts\activate"
python training\train_model.py

🐳 Run with Docker

Compose services:

  • api – FastAPI app (port 8000)
  • frontend – Built with Node, served via Nginx (port 5173)
  • redis – Redis cache (port 6379)
  • prometheus – Metrics collection (port 9090)
  • grafana – Dashboards (port 3000)

Start:

cd /d "D:\CODES\CampusX\FastAPI Capstone Project"
docker compose up --build

Stop:

docker compose down

πŸ› οΈ Troubleshooting

  • Proxy error from Vite (ECONNREFUSED /login): start the backend (uvicorn ...) or run via Docker Compose.
  • 401 Unauthorized: missing/invalid token header – login again and include the JWT.
  • 403 Forbidden: missing/invalid api-key header – set api-key: demo-key (or your configured value).
  • Redis errors: optional in dev – the app now runs even if Redis isn’t available.
  • CORS issues: CORS is permissive in dev; restrict allow_origins in app/main.py for production.

🀝 Contributing

  1. Fork the repo
  2. Create a branch: git checkout -b feature/YourFeature
  3. Commit: git commit -m "feat: add awesome thing"
  4. Push: git push origin feature/YourFeature
  5. Open a PR

πŸ“„ License

MIT License. See LICENSE file if provided.


Made with ❀️ by Karan Patel