import streamlit as st import speedtest import plotly.graph_objects as go import time # Function to get the best server and calculate average download/upload speeds def get_speed(): st.spinner("Testing your internet speed...") speed_test = speedtest.Speedtest() # Initialize Speedtest instance # Try to retrieve configuration; if it fails, manually choose a server (known good one) try: speed_test.get_best_server() except speedtest.ConfigRetrievalError: st.error("Error retrieving configuration from Speedtest servers. Please check your network.") return None, None, None # Run the speed test multiple times to average the results download_speeds = [] upload_speeds = [] for _ in range(3): # Run the test 3 times for better accuracy download_speeds.append(speed_test.download() / 1_000_000) # Convert to Mbps upload_speeds.append(speed_test.upload() / 1_000_000) # Convert to Mbps time.sleep(1) # Adding a small delay between tests to avoid network congestion # Average the results for more accuracy avg_download_speed = sum(download_speeds) / len(download_speeds) avg_upload_speed = sum(upload_speeds) / len(upload_speeds) # Optionally, add latency information for a more detailed report ping = speed_test.results.ping return avg_download_speed, avg_upload_speed, ping # Function to visualize the speed in a circular gauge with a pointer def plot_speedometer(speed, speed_type): fig = go.Figure(go.Indicator( mode="gauge+number", value=speed, title={'text': f"{speed_type} Speed (Mbps)"}, gauge={ 'axis': {'range': [None, 100]}, # Range of 0 to 100 Mbps 'bar': {'color': "lightblue"}, 'steps': [ {'range': [0, 20], 'color': "red"}, {'range': [20, 50], 'color': "yellow"}, {'range': [50, 100], 'color': "green"} ], 'threshold': { 'line': {'color': "black", 'width': 4}, # Pointer color and width 'thickness': 0.75, # Pointer thickness 'value': speed # Set the pointer to the current speed value } } )) fig.update_layout(height=300) st.plotly_chart(fig) # Main app def main(): st.title("Internet Speed Test") st.write("Press the button below to test your download and upload speeds.") # Button to start the speed test if st.button("Start Speed Test"): download_speed, upload_speed, ping = get_speed() # Check if the speed test was successful if download_speed is None or upload_speed is None: return # Display the results st.subheader(f"Download Speed: {download_speed:.2f} Mbps") st.subheader(f"Upload Speed: {upload_speed:.2f} Mbps") st.subheader(f"Ping: {ping} ms") # Display ping for further insights # Visualize the speeds with circular speedometers including pointers plot_speedometer(download_speed, "Download") plot_speedometer(upload_speed, "Upload") if __name__ == "__main__": main()