This commit is contained in:
Matt Johnson 2017-10-16 16:19:48 +00:00 committed by GitHub
commit 2d1f77bfa2
4 changed files with 96 additions and 3 deletions

13
Dockerfile Normal file
View File

@ -0,0 +1,13 @@
FROM ubuntu
MAINTAINER @mattdashj
RUN apt-get update
RUN apt-get install -y \
python3 \
python3-pip \
git \
&& true
RUN pip3 install plotly
RUN mkdir ~/.plotly
COPY * /speedtest-cli/
CMD ["python3", "/speedtest-cli/speedtest.py", "--plotly"]

View File

@ -76,7 +76,7 @@ Usage
$ speedtest-cli -h $ speedtest-cli -h
usage: speedtest-cli [-h] [--no-download] [--no-upload] [--bytes] [--share] usage: speedtest-cli [-h] [--no-download] [--no-upload] [--bytes] [--share]
[--simple] [--csv] [--csv-delimiter CSV_DELIMITER] [--simple] [--csv] [--csv-delimiter CSV_DELIMITER]
[--csv-header] [--json] [--list] [--server SERVER] [--csv-header] [--json] [--plotly] [--list] [--server SERVER]
[--mini MINI] [--source SOURCE] [--timeout TIMEOUT] [--mini MINI] [--source SOURCE] [--timeout TIMEOUT]
[--secure] [--no-pre-allocate] [--version] [--secure] [--no-pre-allocate] [--version]
@ -104,6 +104,9 @@ Usage
--json Suppress verbose output, only show basic information --json Suppress verbose output, only show basic information
in JSON format. Speeds listed in bit/s and not in JSON format. Speeds listed in bit/s and not
affected by --bytes affected by --bytes
--plotly Suppress output, send download, upload, and latency measurements,
plotted over current time and date to plotly. Speeds listed
in bits/s and not affected by --bytes. (See plotly section below)
--list Display a list of speedtest.net servers sorted by --list Display a list of speedtest.net servers sorted by
distance distance
--server SERVER Specify a server ID to test against --server SERVER Specify a server ID to test against
@ -145,3 +148,26 @@ There are several concepts to be aware of that factor into the potential inconsi
Issues relating to inconsistencies will be closed as wontfix and without Issues relating to inconsistencies will be closed as wontfix and without
additional reason or context. additional reason or context.
Plotly
------
Plotly integration was designed to answer the question "is my connection reasonably consistent"
without having to have infrastructure to record, graph, etc.
`Plot.ly <http://plot.ly>`_.
is a free service for hosting graphs, the `--plotly` option depends/expects your plotly
API credentials in `~/.plotly/.credentials`.
See here for more information: `Plotly getting started <https://plot.ly/python/getting-started/>`_.
The output will be the URL to the graph. Subsequent runs of the `speedtest-cli --plotly` will append
to the same graph, giving you a nice trend over time.
To run this, there is also a Dockerfile which can be used to package up and run at intervals.
for example, I have the following set in my crontab to run every hour;
```
docker run -v /root/.plotly:/root/.plotly trxuk/speedtest-plotly:1
```
You could use this command directly as the image is on docker hub, just ensure your `-v`
volume mount to your `.plotly` directory (for the credentials) is correct.

View File

@ -58,6 +58,11 @@ Print CSV headers
Suppress verbose output, only show basic information in JSON format. Speeds listed in bit/s and not affected by \-\-bytes Suppress verbose output, only show basic information in JSON format. Speeds listed in bit/s and not affected by \-\-bytes
.RE .RE
\fB\-\-plotly\fR
.RS
Suppress output, send download, upload, and latency measurements, plotted over current time and date to plotly. Speeds listed in bits/s and not affected by \-\-bytes
.RE
\fB\-\-list\fR \fB\-\-list\fR
.RS .RS
Display a list of speedtest.net servers sorted by distance Display a list of speedtest.net servers sorted by distance

View File

@ -78,6 +78,11 @@ except ImportError:
from xml.dom import minidom as DOM from xml.dom import minidom as DOM
ET = None ET = None
try:
import plotly
except ImportError:
plotly = None
try: try:
from urllib2 import urlopen, Request, HTTPError, URLError from urllib2 import urlopen, Request, HTTPError, URLError
except ImportError: except ImportError:
@ -734,6 +739,40 @@ class SpeedtestResults(object):
}) })
return json.dumps(self.dict(), **kwargs) return json.dumps(self.dict(), **kwargs)
def plotly(self, pretty=False):
"""Uploads results to plotly for graphing against current date. Returns the URL to the plotly graph."""
# Results data from MAIN
data = self.dict()
import plotly as plotly
##plotly.tools.set_credentials_file(username='matjohn2', api_key='SNgbbnB3KmpjLRfybBAD')
uploadtrace = plotly.graph_objs.Scatter(
x = data['timestamp'],
y = data['upload'],
mode = 'lines+markers',
name = 'Upload'
)
downloadtrace = plotly.graph_objs.Scatter(
x = data['timestamp'],
y = data['download'],
mode = 'lines+markers',
name = 'Download'
)
latencytrace = plotly.graph_objs.Scatter(
x = data['timestamp'],
y = data['ping'],
mode = 'markers',
name = 'Latency'
)
plotdata = [uploadtrace, downloadtrace, latencytrace]
plot_url = plotly.plotly.plot(plotdata, filename='SpeedtestCLI', fileopt='extend', auto_open=False)
return plot_url
class Speedtest(object): class Speedtest(object):
"""Class for performing standard speedtest.net testing operations""" """Class for performing standard speedtest.net testing operations"""
@ -1270,6 +1309,11 @@ def parse_args():
help='Suppress verbose output, only show basic ' help='Suppress verbose output, only show basic '
'information in JSON format. Speeds listed in ' 'information in JSON format. Speeds listed in '
'bit/s and not affected by --bytes') 'bit/s and not affected by --bytes')
parser.add_argument('--plotly', action='store_true', default=False,
help='Suppress output, send download, upload, '
'and latency measurements, plotted over '
'current time and date to plotly. Speeds '
'listed in bits/s and not affected by --bytes')
parser.add_argument('--list', action='store_true', parser.add_argument('--list', action='store_true',
help='Display a list of speedtest.net servers ' help='Display a list of speedtest.net servers '
'sorted by distance') 'sorted by distance')
@ -1312,6 +1356,7 @@ def validate_optional_args(args):
optional_args = { optional_args = {
'json': ('json/simplejson python module', json), 'json': ('json/simplejson python module', json),
'secure': ('SSL support', HTTPSConnection), 'secure': ('SSL support', HTTPSConnection),
'plotly': ('The Plotly python module', plotly),
} }
for arg, info in optional_args.items(): for arg, info in optional_args.items():
@ -1380,12 +1425,12 @@ def shell():
# Pre-cache the user agent string # Pre-cache the user agent string
build_user_agent() build_user_agent()
if args.simple or args.csv or args.json: if args.simple or args.csv or args.json or args.plotly:
quiet = True quiet = True
else: else:
quiet = False quiet = False
if args.csv or args.json: if args.csv or args.json or args.plotly:
machine_format = True machine_format = True
else: else:
machine_format = False machine_format = False
@ -1489,6 +1534,10 @@ def shell():
results.share() results.share()
print_(results.json()) print_(results.json())
elif args.plotly:
print("Plotly graph at: " + results.plotly())
if args.share and not machine_format: if args.share and not machine_format:
printer('Share results: %s' % results.share()) printer('Share results: %s' % results.share())