Spaces:
Sleeping
Sleeping
File size: 4,237 Bytes
e8f8734 c713165 e8f8734 dd2d99b e8f8734 c713165 e8f8734 c713165 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
from fastapi import FastAPI, HTTPException, Request
from fastapi.responses import HTMLResponse
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
from pydantic import BaseModel, validator
import pandas as pd
import pickle, uvicorn, os, logging
# API Config
app = FastAPI(
title="Devices Price Prediction API",
description="This is a ML API for classifying devices price based on the specs",
)
## Configure static and template files
app.mount(
"/static", StaticFiles(directory="assets/static"), name="static"
) # Mount static files
templates = Jinja2Templates(directory="assets/templates") # Mount templates for HTML
# Configure logging
logging.basicConfig(level=logging.INFO)
# Define filepath for ml_components.pkl
ML_COMPONENTS_FILEPATH = os.path.join("assets", "ml", "ml_components.pkl")
# Load machine learning model and other components
with open(ML_COMPONENTS_FILEPATH, "rb") as file:
ml_components = pickle.load(file)
# preprocessor = ml_components["preprocessor"]
pipeline = ml_components["pipeline"]
class DeviceSpecs(BaseModel):
"""
Device specifications.
- battery_power: Total energy a battery can store in one time measured in mAh
- blue: Has Bluetooth or not (0 for False, 1 for True)
- clock_speed: The speed at which the microprocessor executes instructions
- dual_sim: Has dual sim support or not (0 for False, 1 for True)
- fc: Front Camera megapixels
- four_g: Has 4G or not (0 for False, 1 for True)
- int_memory: Internal Memory in Gigabytes
- m_dep: Mobile Depth in cm
- mobile_wt: Weight of mobile phone
- n_cores: Number of cores of the processor
- pc: Primary Camera megapixels
- px_height: Pixel Resolution Height
- px_width: Pixel Resolution Width
- ram: Random Access Memory in Megabytes
- sc_h: Screen Height of mobile in cm
- sc_w: Screen Width of mobile in cm
- talk_time: longest time that a single battery charge will last when you are
- three_g: Has 3G or not (0 for False, 1 for True)
- touch_screen: Has touch screen or not (0 for False, 1 for True)
- wifi: Has wifi or not (0 for False, 1 for True)
"""
battery_power: float
blue: int
clock_speed: float
dual_sim: int
fc: float
four_g: int
int_memory: float
m_dep: float
mobile_wt: float
n_cores: float
pc: float
px_height: float
px_width: float
ram: float
sc_h: float
sc_w: float
talk_time: float
three_g: int
touch_screen: int
wifi: int
@validator("blue", "dual_sim", "four_g", "three_g", "touch_screen", "wifi")
def validate_boolean(cls, v):
# Ensure the values are either 0 or 1
if v not in (0, 1):
raise ValueError("Value must be 0 or 1")
return v
@app.post("/predict/{device_id}")
async def predict_price(device_id: int, specs: DeviceSpecs):
"""
Predict the price of a device based on its specifications.
Args:
device_id (int): The ID of the device.
specs (DeviceSpecs): The device specifications.
Returns:
dict: A dictionary containing the input data and predicted price.
"""
try:
logging.info(f"Input request received...")
# Preprocess the data
data = pd.DataFrame([{"device_id": device_id, **specs.dict()}])
logging.info(f"Input as a dataframe\n{data.to_markdown()}\n")
# Predict price
data["predicted_price"] = pipeline.predict(data)
logging.info(
f"Predictions made\n{data[['device_id', 'predicted_price']].to_markdown()}\n"
)
# Return input data and predicted price
return data.to_dict("records")
except Exception as e:
logging.error(
f"An error occurred while processing prediction for device ID {device_id}: {str(e)}"
)
raise HTTPException(status_code=500, detail=str(e))
# Root endpoint to serve index.html template
@app.get("/", response_class=HTMLResponse)
async def root(request: Request):
return templates.TemplateResponse("index.html", {"request": request})
if __name__ == "__main__":
uvicorn.run(app, host="127.0.0.1", port=8000, reload=True)
|