diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..63bc051 --- /dev/null +++ b/Dockerfile @@ -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"] diff --git a/README.rst b/README.rst index 0043b5c..d5b54da 100644 --- a/README.rst +++ b/README.rst @@ -76,7 +76,7 @@ Usage $ speedtest-cli -h usage: speedtest-cli [-h] [--no-download] [--no-upload] [--bytes] [--share] [--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] [--secure] [--no-pre-allocate] [--version] @@ -104,6 +104,9 @@ Usage --json Suppress verbose output, only show basic information in JSON format. Speeds listed in bit/s and not 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 distance --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 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 `_. +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 `_. + +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. diff --git a/speedtest-cli.1 b/speedtest-cli.1 index 9e1befe..3428cd2 100644 --- a/speedtest-cli.1 +++ b/speedtest-cli.1 @@ -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 .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 .RS Display a list of speedtest.net servers sorted by distance diff --git a/speedtest.py b/speedtest.py index 8b8526a..b69a4ef 100755 --- a/speedtest.py +++ b/speedtest.py @@ -78,6 +78,11 @@ except ImportError: from xml.dom import minidom as DOM ET = None +try: + import plotly +except ImportError: + plotly = None + try: from urllib2 import urlopen, Request, HTTPError, URLError except ImportError: @@ -734,6 +739,40 @@ class SpeedtestResults(object): }) 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 for performing standard speedtest.net testing operations""" @@ -1266,6 +1305,11 @@ def parse_args(): help='Suppress verbose output, only show basic ' 'information in JSON format. Speeds listed in ' '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', help='Display a list of speedtest.net servers ' 'sorted by distance') @@ -1308,6 +1352,7 @@ def validate_optional_args(args): optional_args = { 'json': ('json/simplejson python module', json), 'secure': ('SSL support', HTTPSConnection), + 'plotly': ('The Plotly python module', plotly), } for arg, info in optional_args.items(): @@ -1376,12 +1421,12 @@ def shell(): # Pre-cache the user agent string 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 else: quiet = False - if args.csv or args.json: + if args.csv or args.json or args.plotly: machine_format = True else: machine_format = False @@ -1485,6 +1530,10 @@ def shell(): results.share() print_(results.json()) + elif args.plotly: + print("Plotly graph at: " + results.plotly()) + + if args.share and not machine_format: printer('Share results: %s' % results.share())