How to Measure Internet Speed in Python: A Comprehensive Guide with Examples
Measuring internet speed is an essential task in modern development. This functionality is necessary when creating monitoring systems, testing the quality of network connections, and for personal use.
Python offers an efficient solution for automating the process of measuring internet speed. The speedtest library allows you to obtain connection speed data directly from program code.
Why Programmatically Measure Internet Speed?
Automated internet speed measurement solves many practical problems:
- Real-time monitoring of network connection stability
- Control over the quality of internet service provider services
- Integration into IoT systems and network services
- Automation of internet speed reporting
- Identification of network equipment issues
- Network load planning
What is the speedtest Library?
The speedtest library for Python provides programmatic interaction with the popular Speedtest.net service. It provides the ability to conduct comprehensive measurements of internet connection parameters.
Main Features of the Library
The library measures the following key parameters:
- Download Speed
- Upload Speed
- Ping/Latency
- Jitter (delay variability)
- Packet Loss
Installing and Configuring the speedtest Library
Installation Process
To install the library, use the pip package manager. Open a command prompt or terminal and run the following command:
pip install speedtest-cli
The library is named speedtest-cli, but can be used both from the command line and in Python scripts.
Verifying Correct Installation
After installation, it is recommended to check the library's functionality:
import speedtest
print("The speedtest library is installed correctly")
Basic Example of Measuring Internet Speed
Simplest Script for Measurement
import speedtest
st = speedtest.Speedtest()
download_speed = st.download() / 1024 / 1024 # Convert to megabits per second
upload_speed = st.upload() / 1024 / 1024 # Convert to megabits per second
ping_result = st.results.ping
print(f"Download Speed: {download_speed:.2f} Mbps")
print(f"Upload Speed: {upload_speed:.2f} Mbps")
print(f"Ping: {ping_result:.2f} ms")
Typical Execution Result
Download Speed: 92.34 Mbps
Upload Speed: 25.67 Mbps
Ping: 15.23 ms
How the speedtest Library Works
Speed Measurement Algorithm
The process of measuring internet speed occurs in several stages:
- Determining the user's geographic location
- Selecting the nearest test server
- Measuring the response time to the server
- Downloading test data to measure incoming traffic speed
- Sending test data to measure outgoing traffic speed
- Calculation and provision of results
Technical Details of the Process
The library uses multithreading for more accurate measurements. It creates multiple parallel connections to the server, which allows you to maximize the channel's bandwidth.
Methods and Functions of the speedtest Library
Main Methods
| Method | Description | Return Value |
|---|---|---|
.download() |
Download speed test | Speed in bits/sec |
.upload() |
Upload speed test | Speed in bits/sec |
.results.ping |
Get ping | Time in milliseconds |
.get_servers() |
Get list of servers | Dictionary with servers |
.get_best_server() |
Choose the best server | Server Information |
Additional Methods
# Get client configuration
config = st.get_config()
# Get provider information
client_info = st.results.client
Working with Test Servers
Getting Information about the Nearest Server
st = speedtest.Speedtest()
server_info = st.get_best_server()
print(f"Best server: {server_info['host']}")
print(f"Country: {server_info['country']}")
print(f"Distance: {server_info['d']:.2f} km")
print(f"Latency: {server_info['latency']:.2f} ms")
Selecting a Specific Server
# Getting a list of all available servers
servers = st.get_servers()
# Selecting servers from a specific country
russian_servers = [s for s in servers if s['country'] == 'Russia']
# Installing a specific server
st.get_servers([12345]) # where 12345 is the server ID
Creating an Internet Speed Monitoring System
Basic Monitoring Script
import speedtest
import time
from datetime import datetime
def test_speed():
st = speedtest.Speedtest()
download_speed = st.download() / 1024 / 1024
upload_speed = st.upload() / 1024 / 1024
ping_result = st.results.ping
return download_speed, upload_speed, ping_result
def monitor_internet_speed(interval_minutes=60):
while True:
try:
now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
download, upload, ping = test_speed()
print(f"[{now}] Download: {download:.2f} Mbps | "
f"Upload: {upload:.2f} Mbps | Ping: {ping:.2f} ms")
time.sleep(interval_minutes * 60)
except Exception as e:
print(f"Error measuring: {e}")
time.sleep(300) # Retry after 5 minutes on error
# Starting monitoring
monitor_internet_speed(60)
Advanced Monitoring Functionality
The monitoring system can include additional features:
- Determining the minimum and maximum speed over a period
- Calculating average values
- Tracking anomalies in connection speed
- Visualizing data in the form of graphs
Saving Measurement Results
Logging to a CSV File
import csv
from datetime import datetime
def initialize_csv():
with open("internet_speed_log.csv", mode="w", newline="") as file:
writer = csv.writer(file)
writer.writerow(["Timestamp", "Download (Mbps)", "Upload (Mbps)", "Ping (ms)"])
def log_results(download, upload, ping):
with open("internet_speed_log.csv", mode="a", newline="") as file:
writer = csv.writer(file)
now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
writer.writerow([now, f"{download:.2f}", f"{upload:.2f}", f"{ping:.2f}"])
# Usage
initialize_csv()
download, upload, ping = test_speed()
log_results(download, upload, ping)
Saving in JSON Format
import json
from datetime import datetime
def save_to_json(results):
timestamp = datetime.now().isoformat()
data = {
"timestamp": timestamp,
"download_mbps": results[0],
"upload_mbps": results[1],
"ping_ms": results[2]
}
# Reading existing data
try:
with open("speed_history.json", "r") as file:
history = json.load(file)
except FileNotFoundError:
history = []
# Adding new data
history.append(data)
# Saving the updated history
with open("speed_history.json", "w") as file:
json.dump(history, file, indent=2)
Working via the Command Line
Basic Commands
The speedtest-cli library provides a convenient command-line interface:
# Simple speed test
speedtest
# Output results in JSON format
speedtest --json
# Output results in CSV format
speedtest --csv
# Using a specific server
speedtest --server 12345
Additional Command Line Parameters
# Show a list of available servers
speedtest --list
# Measure only download speed
speedtest --no-upload
# Measure only upload speed
speedtest --no-download
# Output results in bytes
speedtest --bytes
Handling Errors and Exceptions
Typical Errors and Their Solutions
import speedtest
import time
def safe_speed_test(max_retries=3):
for attempt in range(max_retries):
try:
st = speedtest.Speedtest()
# Setting a timeout for operations
st.get_best_server()
download = st.download() / 1024 / 1024
upload = st.upload() / 1024 / 1024
ping = st.results.ping
return download, upload, ping
except speedtest.ConfigRetrievalError:
print("Error retrieving configuration. Check your internet connection.")
except speedtest.ServersRetrievalError:
print("Failed to retrieve server list.")
except Exception as e:
print(f"An error occurred: {e}")
if attempt < max_retries - 1:
print(f"Retrying in 10 seconds...")
time.sleep(10)
return None, None, None
Integration with Notification Systems
Sending Results by Email
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
def send_speed_report(download, upload, ping, recipient_email):
sender_email = "your_email@gmail.com"
sender_password = "your_password"
message = MIMEMultipart()
message["From"] = sender_email
message["To"] = recipient_email
message["Subject"] = "Internet Speed Report"
body = f"""
Internet speed measurement results:
Download speed: {download:.2f} Mbps
Upload speed: {upload:.2f} Mbps
Ping: {ping:.2f} ms
Measurement time: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
"""
message.attach(MIMEText(body, "plain"))
with smtplib.SMTP("smtp.gmail.com", 587) as server:
server.starttls()
server.login(sender_email, sender_password)
server.send_message(message)
Optimizing Measurement Performance
Configuring Test Parameters
st = speedtest.Speedtest()
# Setting the number of threads for testing
st.download(threads=10)
st.upload(threads=10)
# Configuring the size of data blocks
st.download_config['threadsperurl'] = 8
st.upload_config['threadsperurl'] = 8
Minimizing Network Impact
When monitoring regularly, it is important to consider the load on the network:
- Use reasonable intervals between tests
- Avoid running multiple tests simultaneously
- Schedule tests during periods of minimal load
- Use limits on the amount of data transferred
Visualizing Measurement Results
Creating Graphs Using Matplotlib
import matplotlib.pyplot as plt
import pandas as pd
def visualize_speed_history(csv_file):
# Reading data from CSV
df = pd.read_csv(csv_file)
df['Timestamp'] = pd.to_datetime(df['Timestamp'])
# Creating a graph
plt.figure(figsize=(12, 6))
plt.subplot(2, 1, 1)
plt.plot(df['Timestamp'], df['Download (Mbps)'], label='Download', color='blue')
plt.plot(df['Timestamp'], df['Upload (Mbps)'], label='Upload', color='red')
plt.xlabel('Time')
plt.ylabel('Speed (Mbps)')
plt.title('Internet Speed History')
plt.legend()
plt.grid(True)
plt.subplot(2, 1, 2)
plt.plot(df['Timestamp'], df['Ping (ms)'], label='Ping', color='green')
plt.xlabel('Time')
plt.ylabel('Ping (ms)')
plt.title('Latency History')
plt.legend()
plt.grid(True)
plt.tight_layout()
plt.show()
Frequently Asked Questions
Can I select a specific server for the test?
Yes, the library allows you to select servers for testing. The get_servers() method returns a list of available servers. The get_best_server() method automatically selects the best server based on latency.
Why does the speed in the script differ from the results on the speedtest.net website?
Differences in results can be caused by several factors:
- Using different test servers
- Different network load at the time of testing
- Different measurement algorithms
- The influence of other applications on the computer
- Features of network equipment
How to configure the measurement frequency?
The measurement frequency is controlled by the time.sleep() parameter. For measurements every 10 minutes, use:
time.sleep(600) # 600 seconds = 10 minutes
Can I run the script as a background service?
The script can be run as a system service. In Linux, use cron to schedule tasks. In Windows, use the Task Scheduler to automatically start.
How to limit the number of tests?
To limit the number of tests, add a counter:
test_count = 0
max_tests = 10
while test_count < max_tests:
# Test execution
test_count += 1
How to implement low-speed notifications?
MIN_DOWNLOAD_SPEED = 50 # Minimum speed in Mbps
def check_speed_threshold(download_speed):
if download_speed < MIN_DOWNLOAD_SPEED:
# Sending a notification
send_alert(f"Low download speed: {download_speed:.2f} Mbps")
Recommendations for Use
Best Practices
When developing an internet speed monitoring system, follow these recommendations:
- Log all measurement results for later analysis
- Use exception handling for stable operation
- Configure alerts for critical speed changes
- Regularly clean up old logs to save space
- Document threshold values for your network
Security and Privacy
When using the speedtest library, consider security aspects:
- Data is transmitted to Speedtest.net servers
- The IP address and approximate location may be registered
- Test results may be visible to the provider
The Future of AI in Mathematics and Everyday Life: How Intelligent Agents Are Already Changing the Game
Experts warned about the risks of fake charity with AI
In Russia, universal AI-agent for robots and industrial processes was developed