2015-11-12 36 views
8

Sto provando a creare un semplice server Python per testare il mio frontend. Dovrebbe essere in grado di gestire le richieste GET e POST. I dati devono essere sempre in formato JSON fino a quando non vengono tradotti in richiesta/risposta HTTP. Dovrebbe essere chiamato uno script con il nome corrispondente per gestire ogni richiesta.Semplice server Python per elaborare richieste GET e POST con JSON

server.py

#!/usr/bin/env python 

from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer 
import SocketServer 
import json 
import urlparse 
import subprocess 

class S(BaseHTTPRequestHandler): 
    def _set_headers(self): 
     self.send_response(200) 
     self.send_header('Content-type', 'application/json') 
     self.end_headers() 

    def do_GET(self): 
     self._set_headers() 
     parsed_path = urlparse.urlparse(self.path) 
     request_id = parsed_path.path 
     response = subprocess.check_output(["python", request_id]) 
     self.wfile.write(json.dumps(response)) 

    def do_POST(self): 
     self._set_headers() 
     parsed_path = urlparse.urlparse(self.path) 
     request_id = parsed_path.path 
     response = subprocess.check_output(["python", request_id]) 
     self.wfile.write(json.dumps(response)) 

    def do_HEAD(self): 
     self._set_headers() 

def run(server_class=HTTPServer, handler_class=S, port=8000): 
    server_address = ('', port) 
    httpd = server_class(server_address, handler_class) 
    print 'Starting httpd...' 
    httpd.serve_forever() 

if __name__ == "__main__": 
    from sys import argv 

    if len(argv) == 2: 
     run(port=int(argv[1])) 
    else: 
     run() 

Esempio di testscript.py per la gestione delle richieste, che in questo caso solo restituisce un oggetto JSON.

#!/usr/bin/env python 
return {'4': 5, '6': 7} 

Il server deve ritornare ad esempio {'4': 5, '6': 7} per una risposta in formato http://www.domainname.com:8000/testscript.

Il mio problema è che non riesco a capire come passare le variabili in mezzo e ho bisogno di aiuto per farlo funzionare.

+0

Dove vuoi passare le variabili? al server o tra le definizioni nelle classi – Harwee

+0

In questa domanda restituiscono principalmente le variabili tra gli script Python. Ma idealmente mi piacerebbe passare JSON tra Httprequest -> server -> script di gestione -> server -> risposta http –

+0

Dai un'occhiata a questo post correlato che fornisce un server HTTP funzionante che fornisce supporto POST per Python2.7 https: // StackOverflow .com/questions/31371166/reading-json-from-simplehttpserver-post-data – Pierz

risposta

7

Ecco un esempio di client server in python. Sto usando la libreria bottle per gestire le richieste al server e creare il server.

Codice Server

import subprocess 
from bottle import run, post, request, response, get, route 

@route('/<path>',method = 'POST') 
def process(path): 
    return subprocess.check_output(['python',path+'.py'],shell=True) 

run(host='localhost', port=8080, debug=True) 

Si parte server su localhost:8080. È possibile passare il nome del file che si desidera eseguire eseguire. Assicurarsi che il file si trovi nello stesso percorso in cui il codice sopra funziona o cambiare percorso in modo appropriato per l'esecuzione da una directory diversa. Path corrisponde al nome del file e invoca la funzione process quando viene fornito un percorso. Se non riesce a trovare il file, solleva un'eccezione Errore interno del server. Puoi anche chiamare script dalle sottodirectory.

Codice Cliente

import httplib, subprocess 

c = httplib.HTTPConnection('localhost', 8080) 
c.request('POST', '/return', '{}') 
doc = c.getresponse().read() 
print doc 

Si invoca una richiesta POST a localhost:8080/return

return.py

def func(): 
    print {'4': 5, '6': 7} 
func() 

Assicurati si stampa la risposta di uscita come stiamo usando subprocess.check_output() in quanto cattura solo dichiarazioni di stampa.

Usa Popen in subprocess per aprire una connessione continua, invece di check_output passare argomenti a funzionare in server di

Scegli questa documentation su come estrarre POST o GET valori

+0

'@route ('/ ', metodo = 'GET') processo di def (percorso): response.content_type = 'text/html ' return' Hello World GET'' mi sta ancora dando un errore interno del server e non c'è modo di eseguirne il debug. il server funziona sulla porta 800 ma non vi è alcun segno di attività, mentre l'altro server era attivo. –

+0

Puoi approfondire il tuo problema? Il metodo 'GET' che hai postato non dà errori sul mio server e il server funziona su 8080 non 800 – Harwee

+1

Sì, funzionava bene da' localhost' e ho avuto solo problemi ad accedervi dall'esterno. Cambiare 'host = 'localhost'' su' host =' 0.0.0.0'' ha risolto il mio problema e ora posso accedere da fonti esterne. Tutto va bene ora. –

1

Io uso questo:

https://gist.github.com/earonesty/ab07b4c0fea2c226e75b3d538cc0dc55

from apiserve import ApiServer, ApiRoute 

class MyServer(ApiServer): 
     @ApiRoute("/popup") 
     def addbar(req): 
      return {"boo":req["bar"]+1} 

     @ApiRoute("/baz") 
     def justret(req): 
      if req: 
       raise ApiError(501,"no data in for baz") 
      return {"obj":1} 

MyServer("127.0.0.1",8000).serve_forever() 

Questo particolare wrapper consente di ascoltare facilmente sulla porta 0 (porta alta casuale) che alcune strutture offuscano. Gestisce automaticamente le richieste GET/POST per tutti i percorsi e si unisce negli argomenti URI con gli argomenti dell'oggetto JSON di livello superiore. Che è abbastanza buono per me nella maggior parte dei casi.

È molto più leggero della maggior parte delle strutture. I casi di test in sintesi mostrano meglio come funziona.