Most of you are probably familiar with https://speedtest.net, a website that measures the speed of your internet connection and reports your download, upload and ping speeds.
Did you know that Speedtest made a Python module for it? It is called speedtest-cli
, and it's a little old but still works admirably well. I'm going to show you how to use it to measure your network speed from within Python?
What if I told you that this speedtest-cli
module powers the speedtest-cli command line program as well? The one referenced in their announcement. It may even be powering the main speedtest.net site as well.
So by understanding how this program works, you gain the enormous potential of making something scalable using speedtest.net services.
Why measure within Python?
There are some advantages to running a speedtest using an API vs. a shell command.
- You can easily parse the output and errors
- No informational output is printed to standard error
- It is easier to pass arguments to an API call than a shell script called from a Python program.
So let's see how this speedtest-cli thing works, shall we?
The API calls
Installation is dead simple; you just run pip install speedtest-cli
. This doesn't need it's own section.
Note: installing the speedtest-cli module also installs the speedtest-cli command line program.
Getting a list of servers
import speedtest
s = speedtest.Speedtest()
servers = s.get_servers()
This returns 49 speedtest.net servers for now, this number will go up or down depending on if speedtest.net creates and deletes servers, which are hosted by ISPs at their datacenters. The result is a dictionary of servers categorized by distance. In other words, the distances are the dictionary keys, and they are floating-point numbers. The best way to iterate through this structure therefore is using [*s.get_servers().values()]
.
s.get_best_server()
Returns the nearest server, the one with the smallest distance.
s.download(threads=None)
s.upload(threads=None, pre_allocate=True)
These two functions perform the download and upload tests respectively and return similar structures. The threads
keyword argument takes a number that determines the number of threads to use for the test. By default it is None
, which means the speedtest.net server decides how many threads to use.
If pre_allocate=True
(upload()
only), then the entire upload data is stored in memory before running the test. This improves the upload performance and thus result somewhat, but it might cause you to run out of memory on small-memory systems, so you can set it to False
to disable that, and store the upload data piece by piece.
s.results.share()
Makes an HTTP POST request to speedtest.net with your results and returns a link to an image of your results, such as this:
Thanks for reading
If you see any errors in this post, please let me know so I can correct them.