2016-01-19 7 views
6

E 'possibile ottenere Plotly (utilizzato da Python) come "strettamente locale"? In altre parole, è possibile utilizzarlo in un modo che garantisca che non contatterà la rete per nessun motivo?Disabilita Plotly in Python dalla comunicazione con la rete in qualsiasi forma

Questo include cose come il programma che tenta di contattare il servizio Plotly (poiché questo era il modello di business), e anche cose come assicurarsi di cliccare ovunque nell'Html generato non avranno né un link a Plotly né altrove.

Naturalmente, mi piacerebbe poterlo fare su una macchina di produzione connessa alla rete, quindi non è possibile estrarre la connessione di rete.

+0

Hai trovato una soluzione migliore? – LauriK

+0

@LauriK non così lontano. – PonyEars

risposta

1

Penso di aver trovato una soluzione per questo. Innanzitutto, è necessario scaricare il file Plotly.js open source file. Quindi ho una funzione, scritta di seguito, che produrrà il javascript dalla trama python e farà riferimento alla tua copia locale di plotly-latest.min.js. Vedi sotto:

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') 

Le linee principali che toglie tutti i collegamenti sono:

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

Si potrebbe chiamare il fuction in quanto tale, per ottenere un file HTML statico che fa riferimento la copia locale del plotly open biblioteca origine:

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

Grazie, è utile. Il mio scopo nel porre la domanda era principalmente quello di verificare se esistesse un'API incorporata per evitare qualsiasi comunicazione di rete, o persino un meccanismo di "accesso alla rete di spegnimento", ad esempio, non importando un modulo che eseguisse le comunicazioni di rete. Il motivo è di garantire che i dati riservati non perdano. La tua risposta fornisce un modo per farlo funzionare con link locali, che è prezioso ma non offre questa garanzia. – PonyEars

0

Anche un semplice import plotly tenta già di connettersi alla rete come illustrato nell'esempio seguente:

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

Il risultato è:

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

Il collegamento avviene quando il get_graph_reference() function è chiamato while the graph_reference module is initialized.

Un modo per evitare la connessione ai server plot.ly è impostare un valore plotly_api_domain non valido in ~/.plotly/.config. Per me, questa non è un'opzione in quanto il software viene eseguito sulla macchina del client e non voglio modificare il loro file di configurazione. Inoltre, it is also not yet possible to change the configuration directory through an environment variable.

Un work-around è quello di scimmia-patch requests.get prima di importare 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 

Questo non è sicuramente una soluzione completa, ma, se non altro, questo dimostra che plot.ly non è attualmente destinata ad essere funziona completamente offline.

0

Non ho fatto alcun test approfonditi, ma sembra che Plot.ly offre una modalità "offline":

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

Un semplice esempio:

from plotly.offline import plot 
from plotly.graph_objs import Scatter 

plot([Scatter(x=[1, 2, 3], y=[3, 1, 6])]) 

È possibile installare Tracciare.LY via pip e quindi eseguire lo script precedente per produrre un file HTML statico:

$ pip install plotly 
$ python ./above_script.py 

Quando eseguo questo dal Terminal mio browser web si apre al seguente URL del file:

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

Ciò rende un Interact grafico completamente locale per il tuo file system.