import streamlit as st import pandas as pd import joblib import plotly.express as px import numpy as np # Page configuration st.set_page_config( page_title="API Status Code Predictor", page_icon="📡", layout="wide" ) # Custom CSS for better styling st.markdown(""" """, unsafe_allow_html=True) # Load model with caching @st.cache_resource def load_model(): # Use a raw string to handle Windows path separators model_path = "status_code_classifier.pkl" return joblib.load(model_path) try: model = load_model() model_loaded = True except Exception as e: st.error(f"⚠️ Model file not found or failed to load: {e}") model_loaded = False # Create a dummy model for UI demonstration class DummyModel: def __init__(self): self.classes_ = np.array([200, 400, 500]) def predict(self, X): return np.array([200]) def predict_proba(self, X): return np.array([[0.75, 0.15, 0.10]]) model = DummyModel() # Header section st.markdown("

📡 API Status Code Predictor

", unsafe_allow_html=True) st.markdown( "

Analyze API behaviors and predict response status codes based on request parameters

", unsafe_allow_html=True) # Create two columns for layout col1, col2 = st.columns([3, 5]) # Sidebar with inputs - now moved to a card in the left column with col1: st.markdown("
", unsafe_allow_html=True) st.subheader("📝 Request Parameters") # API and Environment selection with more informative labels api_options = { "OrderProcessor": "Order Processing API", "AuthService": "Authentication Service", "ProductCatalog": "Product Catalog API", "PaymentGateway": "Payment Gateway" } api_id = st.selectbox("API Service", list(api_options.keys()), format_func=lambda x: api_options[x]) env = st.selectbox( "Environment", ["production-useast1", "staging"], format_func=lambda x: f"{'Production (US East)' if x == 'production-useast1' else 'Staging'}" ) # More organized parameter inputs with tooltips st.subheader("⚙️ Performance Metrics") latency_ms = st.slider( "Latency (ms)", min_value=0.0, max_value=100.0, value=10.0, help="Response time in milliseconds" ) bytes_transferred = st.slider( "Bytes Transferred", min_value=0, max_value=15000, value=500, help="Size of data transferred in bytes" ) st.subheader("🔄 Request Context") hour_of_day = st.select_slider( "Hour of Day", options=list(range(24)), value=12, format_func=lambda x: f"{x:02d}:00" ) cpu_cost = st.slider( "CPU Cost", min_value=0.0, max_value=50.0, value=10.0, help="Computational resources used" ) memory_mb = st.slider( "Memory Usage (MB)", min_value=0.0, max_value=100.0, value=25.0, help="Memory consumption in megabytes" ) # Add a predict button to make prediction more intentional predict_button = st.button("🔮 Predict Status Code", use_container_width=True) st.markdown("
", unsafe_allow_html=True) # Mapping to codes - moved after selection api_id_code = {"OrderProcessor": 2, "AuthService": 0, "ProductCatalog": 1, "PaymentGateway": 3}[api_id] env_code = {"production-useast1": 1, "staging": 0}[env] # Input for prediction input_data = pd.DataFrame([[api_id_code, env_code, latency_ms, bytes_transferred, hour_of_day, cpu_cost, memory_mb]], columns=['api_id', 'env', 'latency_ms', 'bytes_transferred', 'hour_of_day', 'simulated_cpu_cost', 'simulated_memory_mb']) # Results section on the right with col2: if predict_button or not model_loaded: # Predict prediction = model.predict(input_data)[0] probabilities = model.predict_proba(input_data) # Format prediction results status_codes = { 200: "Success (200)", 400: "Client Error (400)", 500: "Server Error (500)" } status_class = { 200: "status-200", 400: "status-400", 500: "status-500" } # Display the prediction in a card st.markdown("
", unsafe_allow_html=True) st.subheader("🎯 Prediction Result") st.markdown( f"

Most likely status code:

{prediction}

{status_codes.get(prediction, 'Unknown')}

", unsafe_allow_html=True) # Show prediction confidence prob_dict = {int(model.classes_[i]): float(probabilities[0][i]) for i in range(len(model.classes_))} confidence = prob_dict[prediction] * 100 st.write(f"Confidence: {confidence:.1f}%") st.markdown("
", unsafe_allow_html=True) # Show probability distribution with a horizontal bar chart st.markdown("
", unsafe_allow_html=True) st.subheader("📊 Probability Distribution") # Create dataframe for visualization prob_df = pd.DataFrame({ 'Status Code': [f"{int(code)} - {status_codes.get(int(code), 'Unknown')}" for code in model.classes_], 'Probability': probabilities[0] }) # Create a bar chart using Plotly fig = px.bar( prob_df, x='Probability', y='Status Code', orientation='h', color='Status Code', color_discrete_map={ f"200 - {status_codes.get(200)}": '#4CAF50', f"400 - {status_codes.get(400)}": '#FF9800', f"500 - {status_codes.get(500)}": '#F44336' } ) fig.update_layout( height=300, margin=dict(l=20, r=20, t=30, b=20), xaxis_title="Probability", yaxis_title="", xaxis=dict(tickformat=".0%") ) st.plotly_chart(fig, use_container_width=True) st.markdown("
", unsafe_allow_html=True) # Parameters influence section st.markdown("
", unsafe_allow_html=True) st.subheader("🔍 Feature Importance") st.write("How different parameters influence the prediction:") # Mock feature importance for demonstration feature_importance = { 'API Service': 0.25, 'Environment': 0.15, 'Latency': 0.20, 'Bytes Transferred': 0.10, 'Time of Day': 0.05, 'CPU Cost': 0.15, 'Memory Usage': 0.10 } # Create a horizontal bar chart for feature importance importance_df = pd.DataFrame({ 'Feature': list(feature_importance.keys()), 'Importance': list(feature_importance.values()) }).sort_values('Importance', ascending=False) fig_importance = px.bar( importance_df, x='Importance', y='Feature', orientation='h', color='Importance', color_continuous_scale='Blues' ) fig_importance.update_layout( height=350, margin=dict(l=20, r=20, t=20, b=20), yaxis_title="", coloraxis_showscale=False ) st.plotly_chart(fig_importance, use_container_width=True) st.markdown("
", unsafe_allow_html=True) # Footer with information st.markdown("---") st.markdown( "💡 **About**: This tool uses machine learning to predict API response status codes based on request parameters and system metrics.")