How to measure internet speed in Python?

онлайн тренажер по питону
Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

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

News