Disable Plotly in Python from communicating with the network in any form

Is it possible for Plotly (used from Python) to be "strictly local"? In other words, is it possible to use it in such a way as to guarantee that it will not contact the network for any reason?

This includes things like a program trying to contact the Plotly service (since it was a business model), as well as things such as providing a click anywhere in the generated html, will not have a link to Plotly or elsewhere .

Of course, I would like to be able to do this on a production machine connected to the network, so turning off the network connection is not an option.

+6
source share
3 answers

I think I have a solution for this. First, you need to download the open source file Plotly.js. Then I have a function written below that will call javascript from the python graph and reference your local copy of plotly-latest.min.js. See below:

import sys import os from plotly import session, tools, utils import uuid import json def get_plotlyjs(): path = os.path.join('offline', 'plotly.min.js') plotlyjs = resource_string('plotly', path).decode('utf-8') return plotlyjs def js_convert(figure_or_data,outfilename, show_link=False, link_text='Export to plot.ly', validate=True): figure = tools.return_figure_from_figure_or_data(figure_or_data, validate) width = figure.get('layout', {}).get('width', '100%') height = figure.get('layout', {}).get('height', 525) try: float(width) except (ValueError, TypeError): pass else: width = str(width) + 'px' try: float(width) except (ValueError, TypeError): pass else: width = str(width) + 'px' plotdivid = uuid.uuid4() jdata = json.dumps(figure.get('data', []), cls=utils.PlotlyJSONEncoder) jlayout = json.dumps(figure.get('layout', {}), cls=utils.PlotlyJSONEncoder) config = {} config['showLink'] = show_link config['linkText'] = link_text config["displaylogo"]=False config["modeBarButtonsToRemove"]= ['sendDataToCloud'] jconfig = json.dumps(config) plotly_platform_url = session.get_session_config().get('plotly_domain', 'https://plot.ly') if (plotly_platform_url != 'https://plot.ly' and link_text == 'Export to plot.ly'): link_domain = plotly_platform_url\ .replace('https://', '')\ .replace('http://', '') link_text = link_text.replace('plot.ly', link_domain) script = '\n'.join([ 'Plotly.plot("{id}", {data}, {layout}, {config}).then(function() {{', ' $(".{id}.loading").remove();', '}})' ]).format(id=plotdivid, data=jdata, layout=jlayout, config=jconfig) html="""<div class="{id} loading" style="color: rgb(50,50,50);"> Drawing...</div> <div id="{id}" style="height: {height}; width: {width};" class="plotly-graph-div"> </div> <script type="text/javascript"> {script} </script> """.format(id=plotdivid, script=script, height=height, width=width) #html = html.replace('\n', '') with open(outfilename, 'wb') as out: #out.write(r'<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>') out.write(r'<script src="plotly-latest.min.js"></script>') for line in html.split('\n'): out.write(line) out.close() print ('JS Conversion Complete') 

The key lines that take away all the links are:

 config['showLink'] = show_link #False .... config["modeBarButtonsToRemove"]= ['sendDataToCloud'] 

You would call fuction as such to get a static HTML file that references your local copy of the open source conspiracy library:

 fig = { "data": [{ "x": [1, 2, 3], "y": [4, 2, 5] }], "layout": { "title": "hello world" } } js_convert(fig, 'test.html') 
+1
source

Even a simple import plotly already trying to connect to the network, as shown in this example:

 import logging logging.basicConfig(level=logging.INFO) import plotly 

Output:

 INFO:requests.packages.urllib3.connectionpool:Starting new HTTPS connection (1): api.plot.ly 

The connection is made when the get_graph_reference () function is called , while the graph_reference module is initialized .

One way to avoid connecting to plot.ly servers is to set the invalid plotly_api_domain to ~/.plotly/.config . This is not an option for me, because the software runs on the client machine, and I do not want to change their configuration file. In addition, it is also not possible to change the configuration directory through an environment variable .

One workaround is the monkey-patch requests.get before importing plotly:

 import requests import inspect original_get = requests.get def plotly_no_get(*args, **kwargs): one_frame_up = inspect.stack()[1] if one_frame_up[3] == 'get_graph_reference': raise requests.exceptions.RequestException return original_get(*args, **kwargs) requests.get = plotly_no_get import plotly 

This, of course, is not a complete solution, but, if nothing else, it shows that plot.ly is not currently intended to run autonomously.

0
source

I have not done extensive testing, but it seems that Plot.ly offers a "standalone" mode:

https://plot.ly/python/offline/

A simple example:

 from plotly.offline import plot from plotly.graph_objs import Scatter plot([Scatter(x=[1, 2, 3], y=[3, 1, 6])]) 

You can install Plot.ly via pip and then run the above script to create a static HTML file:

 $ pip install plotly $ python ./above_script.py 

When I launched this from the terminal, my web browser opens the following file URL:

 file:///some/path/to/temp-plot.html 

This displays an interaction schedule that is completely local to your file system.

0
source

All Articles