2010-07-20 19 views
7

Questa è la mia prima domanda qui, quindi spero che sarà fatta correttamente;)Web-ifing uno script da riga di comando Python?

Mi è stato assegnato l'incarico di fornire un'interfaccia web ad alcuni script python "fatti in casa". Questo script viene utilizzato per verificare la disponibilità di alcuni siti Web/applicazioni, tramite i comandi di arricciatura. Un aspetto molto importante di questo script è che dà i suoi risultati in tempo reale, scrivendo riga per riga sullo standard output.

Fornendo un'interfaccia Web a questo script, l'obiettivo principale è che lo script possa essere facilmente utilizzato da qualsiasi luogo, ad esempio tramite uno smartphone. Quindi l'interfaccia web deve essere abbastanza semplice e funzionare "senza plugin".

Il mio problema è che la maggior parte delle soluzioni che ho pensato o trovato sul web (ajax, django, anche un semplice post) sembrano aver bisogno di un'intera generazione della pagina prima di inviarla al browser, perdendo questo importante "reale" tempo "aspetto.

Qualche idea su come farlo correttamente?

Grazie in anticipo.

+0

Grazie per le vostre risposte, io sono attualmente impegnato su altri compiti, ma dovrei tornare su questo ;-) presto – Lenn

risposta

0

Il tuo compito sembra interessante. :-) Uno scenario appena venuto in mente: continuate a scansionare le risorse con i vostri script home-brew e inserite i risultati nel vostro database persistente e un sistema di caching, come Redis, simultaneamente. Il tuo sistema/livello di caching funge da fonte di dati primaria quando serve le richieste dei client. Redis f.e. è un key-value-store ad alte prestazioni che è in grado di gestire 100k connessioni al secondo. Sebbene solo il n più recente (ad esempio le voci 50k) contino, il sistema di caching conserverà solo queste voci e consentirà di concentrarsi esclusivamente sullo sviluppo dell'API lato server (gestione delle connessioni, elaborazione delle richieste, lettura da Redis) e del frontend. La comunicazione tra frontend e backend-API potrebbe essere guidata dalle connessioni WebSocket. Una parte piuttosto nuova delle specifiche HTML5. Sebbene, tuttavia, già supportato da molte versioni del browser rilasciate in questi giorni. In alternativa è possibile eseguire il fallback su alcuni oggetti Flash Socket asincroni. I Websocket consentono fondamentalmente connessioni persistenti tra un client e un server; puoi registrare un listener di eventi che viene chiamato per ogni pacchetto/pacchetto dati in arrivo - nessun polling infinito o altro materiale.

3

Uno schizzo di una soluzione:

creare un file HTML che contiene il layout per la tua pagina web, con un DIV dedicato per l'uscita dello script:

<html> 
<body> 
<div id="scriptoutput"></div> 
<script type="text/javascript" src="localhost:8000/runscript"/> 
</body> 
</html> 

Questo file HTML può essere servito utilizzando qualsiasi server che desideri.

Ora, scrivere un server http semplice, che esegue lo script e converte ogni riga per un comando JavaScript (ad esempio in python):

import os 
f = os.popen('ping 127.0.0.1') 
for i in range(30): 
    ln = f.readline() 
    print "document.getElementById('scriptoutput').innerHTML += '<pre>%s</pre><br/>';" % ln 

È possibile utilizzare qualsiasi server CGI/WSGI per l'attività, o se le prestazioni non sono cruciali, nemmeno usare la classe BaseHTTPServer di Python.

Questo sarebbe il trucco, dato che la maggior parte dei browser analizza ed esegue script Javascript così come vengono ricevuti (e non solo quando la richiesta è completata) - si noti che non è necessario il polling o l'archiviazione sul lato server!

+0

ho dimostrato python2.7 server.py script in esecuzione e modificato per servire la directory di script senza parametri e il codice html come index.html. Corro il codice Python e ottenuto l'errore: file "D: /test/javascr.py", la linea 4, in ln = f.readline() AttributeError: 'tupla' oggetto non ha attributo 'readline' E il browser mostrava una pagina vuota. qualcosa deve essere mancante. Dove inserire il nome dello script Python per l'esecuzione, ad esempio, stampare in modo semplice "Hello world"? –

+0

scusate, avrebbe dovuto essere popen invece di popen2 - risolto. – adamk

0

Spero di aver compreso correttamente la tua necessità.

L'idea alla base di Ajax è di aggiornare il contenuto della pagina senza ricaricare l'intera pagina. Penso che dovrebbe corrispondere alle tue necessità. Potrebbe essere necessario modificare i comandi se si desidera pubblicizzarli.Potrebbe essere necessario ottenere i registri di stampa "al volo".

Ecco alcune idee:

  1. scrivere una pagina molto semplice con la possibilità di eseguire i comandi (menu, form ...)

  2. Quando l'utente chiedere un'esecuzione di comandi, inviare una query ajax al server che esegue il comando.

  3. I comandi devono essere modificati per reindirizzare sys.stdout a qualcosa che memorizzi i registri di stampa in un database. È possibile farlo assegnando a sys.stdout un oggetto con una funzione write.

    class MyDbLogger: 
        def __init__(self, ...): 
         """Some initialization""" 
         ... 
    
        def write(self, s): 
         """write into the database""" 
         ... 
    
    dbout = MyDbLogger(...) 
    sys.stdout = dbout 
    
  4. Il client interroga il server regurlarly per ottenere il contenuto nel database e poi scriverlo nella pagina.

  5. Comet è sicuramente la tecnologia da investigare per avere un comportamento in tempo reale. Ciò eviterà al client di eseguire il polling del server su base regolare. Questo può essere un miglioramento del # 4, ma potrebbe essere un po 'più difficile da implementare.

Spero che aiuta

Problemi correlati