Spaces:
Sleeping
Sleeping
| """ | |
| FASTAPI + GRADIO SERVING APPLICATION - Production-Ready ML Model Serving | |
| ======================================================================== | |
| This application provides a complete serving solution for the Telco Customer Churn model | |
| with both programmatic API access and a user-friendly web interface. | |
| Architecture: | |
| - FastAPI: High-performance REST API with automatic OpenAPI documentation | |
| - Gradio: User-friendly web UI for manual testing and demonstrations | |
| - Pydantic: Data validation and automatic API documentation | |
| """ | |
| from fastapi import FastAPI | |
| from pydantic import BaseModel | |
| import gradio as gr | |
| from src.serving.inference import predict # Core ML inference logic | |
| # Initialize FastAPI application | |
| app = FastAPI( | |
| title="Telco Customer Churn Prediction API", | |
| description="ML API for predicting customer churn in telecom industry", | |
| version="1.0.0" | |
| ) | |
| # === HEALTH CHECK ENDPOINT === | |
| # CRITICAL: Required for AWS Application Load Balancer health checks | |
| def root(): | |
| """ | |
| Health check endpoint for monitoring and load balancer health checks. | |
| """ | |
| return {"status": "ok"} | |
| # === REQUEST DATA SCHEMA === | |
| # Pydantic model for automatic validation and API documentation | |
| class CustomerData(BaseModel): | |
| """ | |
| Customer data schema for churn prediction. | |
| This schema defines the exact 18 features required for churn prediction. | |
| All features match the original dataset structure for consistency. | |
| """ | |
| # Demographics | |
| gender: str # "Male" or "Female" | |
| Partner: str # "Yes" or "No" - has partner | |
| Dependents: str # "Yes" or "No" - has dependents | |
| # Phone services | |
| PhoneService: str # "Yes" or "No" | |
| MultipleLines: str # "Yes", "No", or "No phone service" | |
| # Internet services | |
| InternetService: str # "DSL", "Fiber optic", or "No" | |
| OnlineSecurity: str # "Yes", "No", or "No internet service" | |
| OnlineBackup: str # "Yes", "No", or "No internet service" | |
| DeviceProtection: str # "Yes", "No", or "No internet service" | |
| TechSupport: str # "Yes", "No", or "No internet service" | |
| StreamingTV: str # "Yes", "No", or "No internet service" | |
| StreamingMovies: str # "Yes", "No", or "No internet service" | |
| # Account information | |
| Contract: str # "Month-to-month", "One year", "Two year" | |
| PaperlessBilling: str # "Yes" or "No" | |
| PaymentMethod: str # "Electronic check", "Mailed check", etc. | |
| # Numeric features | |
| tenure: int # Number of months with company | |
| MonthlyCharges: float # Monthly charges in dollars | |
| TotalCharges: float # Total charges to date | |
| # === MAIN PREDICTION API ENDPOINT === | |
| def get_prediction(data: CustomerData): | |
| """ | |
| Main prediction endpoint for customer churn prediction. | |
| This endpoint: | |
| 1. Receives validated customer data via Pydantic model | |
| 2. Calls the inference pipeline to transform features and predict | |
| 3. Returns churn prediction in JSON format | |
| Expected Response: | |
| - {"prediction": "Likely to churn"} or {"prediction": "Not likely to churn"} | |
| - {"error": "error_message"} if prediction fails | |
| """ | |
| try: | |
| # Convert Pydantic model to dict and call inference pipeline | |
| result = predict(data.dict()) | |
| return {"prediction": result} | |
| except Exception as e: | |
| # Return error details for debugging (consider logging in production) | |
| return {"error": str(e)} | |
| # =================================================== # | |
| # === GRADIO WEB INTERFACE === | |
| def gradio_interface( | |
| gender, Partner, Dependents, PhoneService, MultipleLines, | |
| InternetService, OnlineSecurity, OnlineBackup, DeviceProtection, | |
| TechSupport, StreamingTV, StreamingMovies, Contract, | |
| PaperlessBilling, PaymentMethod, tenure, MonthlyCharges, TotalCharges | |
| ): | |
| """ | |
| Gradio interface function that processes form inputs and returns prediction. | |
| This function: | |
| 1. Takes individual form inputs from Gradio UI | |
| 2. Constructs the data dictionary matching the API schema | |
| 3. Calls the same inference pipeline used by the API | |
| 4. Returns user-friendly prediction string | |
| """ | |
| # Construct data dictionary matching CustomerData schema | |
| data = { | |
| "gender": gender, | |
| "Partner": Partner, | |
| "Dependents": Dependents, | |
| "PhoneService": PhoneService, | |
| "MultipleLines": MultipleLines, | |
| "InternetService": InternetService, | |
| "OnlineSecurity": OnlineSecurity, | |
| "OnlineBackup": OnlineBackup, | |
| "DeviceProtection": DeviceProtection, | |
| "TechSupport": TechSupport, | |
| "StreamingTV": StreamingTV, | |
| "StreamingMovies": StreamingMovies, | |
| "Contract": Contract, | |
| "PaperlessBilling": PaperlessBilling, | |
| "PaymentMethod": PaymentMethod, | |
| "tenure": int(tenure), # Ensure integer type | |
| "MonthlyCharges": float(MonthlyCharges), # Ensure float type | |
| "TotalCharges": float(TotalCharges), # Ensure float type | |
| } | |
| # Call same inference pipeline as API endpoint | |
| result = predict(data) | |
| return str(result) # Return as string for Gradio display | |
| # === GRADIO UI CONFIGURATION === | |
| # Build comprehensive Gradio interface with all customer features | |
| demo = gr.Interface( | |
| fn=gradio_interface, | |
| inputs=[ | |
| # Demographics section | |
| gr.Dropdown(["Male", "Female"], label="Gender", value="Male"), | |
| gr.Dropdown(["Yes", "No"], label="Partner", value="No"), | |
| gr.Dropdown(["Yes", "No"], label="Dependents", value="No"), | |
| # Phone services section | |
| gr.Dropdown(["Yes", "No"], label="Phone Service", value="Yes"), | |
| gr.Dropdown(["Yes", "No", "No phone service"], label="Multiple Lines", value="No"), | |
| # Internet services section (key churn predictors) | |
| gr.Dropdown(["DSL", "Fiber optic", "No"], label="Internet Service", value="Fiber optic"), | |
| gr.Dropdown(["Yes", "No", "No internet service"], label="Online Security", value="No"), | |
| gr.Dropdown(["Yes", "No", "No internet service"], label="Online Backup", value="No"), | |
| gr.Dropdown(["Yes", "No", "No internet service"], label="Device Protection", value="No"), | |
| gr.Dropdown(["Yes", "No", "No internet service"], label="Tech Support", value="No"), | |
| gr.Dropdown(["Yes", "No", "No internet service"], label="Streaming TV", value="Yes"), | |
| gr.Dropdown(["Yes", "No", "No internet service"], label="Streaming Movies", value="Yes"), | |
| # Contract and billing section (major churn factors) | |
| gr.Dropdown(["Month-to-month", "One year", "Two year"], label="Contract", value="Month-to-month"), | |
| gr.Dropdown(["Yes", "No"], label="Paperless Billing", value="Yes"), | |
| gr.Dropdown([ | |
| "Electronic check", "Mailed check", | |
| "Bank transfer (automatic)", "Credit card (automatic)" | |
| ], label="Payment Method", value="Electronic check"), | |
| # Numeric features (important for churn prediction) | |
| gr.Number(label="Tenure (months)", value=1, minimum=0, maximum=100), | |
| gr.Number(label="Monthly Charges ($)", value=85.0, minimum=0, maximum=200), | |
| gr.Number(label="Total Charges ($)", value=85.0, minimum=0, maximum=10000), | |
| ], | |
| outputs=gr.Textbox(label="Churn Prediction", lines=2), | |
| title="🔮 Telco Customer Churn Predictor", | |
| description=""" | |
| **Predict customer churn probability using machine learning** | |
| Fill in the customer details below to get a churn prediction. The model uses XGBoost trained on | |
| historical telecom customer data to identify customers at risk of churning. | |
| 💡 **Tip**: Month-to-month contracts with fiber optic internet and electronic check payments | |
| tend to have higher churn rates. | |
| """, | |
| examples=[ | |
| # High churn risk example | |
| ["Female", "No", "No", "Yes", "No", "Fiber optic", "No", "No", "No", | |
| "No", "Yes", "Yes", "Month-to-month", "Yes", "Electronic check", | |
| 1, 85.0, 85.0], | |
| # Low churn risk example | |
| ["Male", "Yes", "Yes", "Yes", "Yes", "DSL", "Yes", "Yes", "Yes", | |
| "Yes", "No", "No", "Two year", "No", "Credit card (automatic)", | |
| 60, 45.0, 2700.0] | |
| ], | |
| theme=gr.themes.Soft() # Professional appearance | |
| ) | |
| # === MOUNT GRADIO UI INTO FASTAPI === | |
| # This creates the /ui endpoint that serves the Gradio interface | |
| # IMPORTANT: This must be the final line to properly integrate Gradio with FastAPI | |
| app = gr.mount_gradio_app( | |
| app, # FastAPI application instance | |
| demo, # Gradio interface | |
| path="/ui" # URL path where Gradio will be accessible | |
| ) |