Created
May 8, 2020 16:15
-
-
Save terabyte/966385a7093f3350b34f6fda8419386a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
import io | |
import json | |
import random | |
import sh | |
import time | |
import smtplib, ssl | |
# these are servers that are both close by and in my testing were able to | |
# produce gigabit readings. | |
servers = [ | |
11208, | |
20875, | |
5024, | |
]; | |
# how many servers to use from our list at any one invocation | |
test_count = 2 | |
# in case wifi gets turned on, ensure we go over gigabit ethernet and error out | |
# if that doesn't work | |
interface = "eno1" | |
# append our log entries here | |
log_file = '/path/to/speedtest.log' | |
# used in report output | |
hostname = sh.hostname('-f') | |
# minimum expected results, in mbit | |
min_download = 650.0 | |
min_upload = 25.0 | |
email_server = "smtp.gmail.com" | |
email_port = 465 | |
email_login = "[email protected]" | |
email_password = "your-password-like-a-newb" | |
destination_emails = [ '[email protected]' ] | |
def bytes_to_mbit(b): | |
return b * 1.0 / 1048576 * 8 | |
def results_to_results_i_care_about(result): | |
ret = dict() | |
ret['z_download_bandwidth'] = result['download']['bandwidth'] | |
ret['z_upload_bandwidth'] = result['upload']['bandwidth'] | |
ret['2_download_mbit'] = bytes_to_mbit(ret['z_download_bandwidth']) | |
ret['3_upload_mbit'] = bytes_to_mbit(ret['z_upload_bandwidth']) | |
secs = time.time() | |
lt = time.localtime(secs) | |
ret['1_date'] = time.strftime("%Y%m%d %H:%M:%S", lt) | |
ret['z_unix_time'] = secs | |
ret['z_server_id'] = result["server"]["id"] | |
ret['z_server_name'] = result["server"]["name"] | |
ret['z_server_location'] = result["server"]["location"] | |
return ret | |
results = [] | |
results_out_of_range = False | |
servers_to_use = random.sample(servers, test_count) | |
for server in servers_to_use: | |
buf = io.StringIO() | |
sh.speedtest('--server-id=%d' % server, '--format=json', '--interface=%s' % interface, _out=buf) | |
result = json.loads(buf.getvalue()) | |
#print(json.dumps(results_to_results_i_care_about(result), sort_keys=True, indent=4)) | |
formatted_result = results_to_results_i_care_about(result) | |
# write data to our log | |
with open(log_file, 'a+') as f: | |
f.write(json.dumps(formatted_result)) | |
# save result for email | |
results.append(formatted_result) | |
# note if the result was out of range | |
if formatted_result['2_download_mbit'] < min_download: | |
results_out_of_range = True | |
if formatted_result['3_upload_mbit'] < min_upload: | |
results_out_of_range = True | |
# only send email if results out of range | |
if not results_out_of_range: | |
sys.exit(0) | |
total_d = 0 | |
total_u = 0 | |
for record in results: | |
total_d = total_d + record["z_download_bandwidth"] | |
total_u = total_u + record["z_upload_bandwidth"] | |
count = len(results) | |
avg_download = "%.2f" % bytes_to_mbit(total_d * 1.0 / count) | |
avg_upload = "%.2f" % bytes_to_mbit(total_u * 1.0 / count) | |
msg = f"""\ | |
Subject: Speed Test Bandwidth Report for {hostname} | |
The average download speed was: {avg_download} mbit | |
The average upload speed was: {avg_upload} mbit | |
The raw records: | |
""" | |
for record in results: | |
msg = msg + json.dumps(record, sort_keys=True, indent=4) + "\n" | |
# https://realpython.com/python-send-email/ | |
with smtplib.SMTP_SSL(email_server, email_port, context=ssl.create_default_context()) as server: | |
server.login(email_login, email_password) | |
for dest in destination_emails: | |
server.sendmail(email_login, destination_emails, msg) | |
To get a list of nearby servers to fill in the server IDs field, run speedtest -L
Finally, this only works with a gmail account you have "insecure applications" enabled on. Not sure if it works with an application password (let me know!).
make a burner gmail account to use if needed.
ah, yes, dependencies:
$ virtualenv .venv
$ source .venv/bin/activate
$ pip install sh
$ ./venv/bin/python /path/to/this/script.py
Tested with python 3.6
if you want to look at the log without your eyes bleeding, I recommend:
$ apt install jq
$ cat ~/speedtest.log | jq -c '[.["1_date"],.["2_download_mbit"], .["3_upload_mbit"]]'
["20200508 00:09:42",806.605842590332,30.75140380859375]
["20200508 00:11:24",828.466194152832,34.02489471435547]
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This requires the official speedtest client, available here: https://www.speedtest.net/apps/cli
Using the open source one (in debian, speedtest-cli package) cannot measure more than 100mbit down in my experience, due to implementation problems.