2015-11-12 15 views
8

Próbuję utworzyć prosty serwer w języku Python, aby przetestować mój frontend. Powinien być w stanie obsłużyć żądania GET i POST. Dane powinny zawsze być w formacie JSON, dopóki nie zostaną przetłumaczone na żądanie/odpowiedź HTTP. Skrypt o odpowiedniej nazwie powinien zostać wywołany, aby obsłużyć każde żądanie.Prosty serwer w języku Python do przetwarzania żądań GET i POST z 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() 

Przykład testscript.py do obsługi żądania, który w tym przypadku po prostu zwraca się obiekt JSON.

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

Serwer powinien na przykład powrócić {'4': 5, '6': 7} na odpowiedź w formacie http://www.domainname.com:8000/testscript.

Moim problemem jest to, że nie mogę wymyślić, jak przekazywać zmienne pomiędzy i potrzebuję pomocy, aby to działało.

+0

Gdzie chcesz przekazać zmienne? do serwera lub między definicjami w klasach – Harwee

+0

W tym pytaniu głównie zwracane są zmienne między skryptami python. Ale najlepiej byłoby przekazać json między Httprequest -> serwer -> skrypt obsługi -> serwer -> odpowiedź http –

+0

Zobacz ten powiązany wpis, który zapewnia działający serwer HTTP zapewniający wsparcie POST dla Python2.7 https: // stackoverflow .pl/questions/31371166/reading-json-from-simplehttpserver-post-data – Pierz

Odpowiedz

7

Oto przykład klienta serwera w python. Używam biblioteki bottle do obsługi żądań do serwera i tworzenia serwera.

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

Zaczyna serwer na localhost:8080. Możesz przekazać nazwę pliku, który chcesz uruchomić. Upewnij się, że plik znajduje się w tej samej ścieżce, aby powyższy kod działał, lub zmień ścieżkę odpowiednio, aby uruchomić go z innego katalogu. Ścieżka odpowiada nazwie pliku i wywołuje funkcję process po podaniu dowolnej ścieżki. Jeśli nie może znaleźć pliku, podnosi wyjątek Wewnętrzny błąd serwera. Możesz także wywoływać skrypty z podkatalogów.

kod klienta

import httplib, subprocess 

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

To wywołuje żądania POST do localhost:8080/return

return.py

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

upewnij się wydrukować odpowiedź wyjściową jak używamy subprocess.check_output() ponieważ przechwytuje tylko instrukcje drukowania.

Zastosowanie Popen w subprocess otwarcie stałego połączenia zamiast check_output przekazywać argumenty do funkcjonowania w serwerze

Sprawdź to documentation na jak wydobyć POST lub GET wartości

+0

'@route ('/ ', method = 'GET') proces def (ścieżka): response.content_type = 'text/html ' return' Hello World GET'' nadal daje mi wewnętrzny błąd serwera i nie ma sposobu na jego debugowanie. twój serwer działa na porcie 800, ale nie ma śladu aktywności, podczas gdy drugi serwer był aktywny. –

+0

Czy możesz rozwinąć swój problem? Wypisana przez ciebie metoda GET nie daje żadnych błędów na moim serwerze i serwer działa na 8080 nie 800 – Harwee

+1

Tak, działało dobrze z 'localhost' i miałem problemy z dostępem do niego z zewnątrz. Zmiana 'host = 'localhost'' na' host =' 0.0.0.0'' rozwiązała mój problem i mogę teraz uzyskać dostęp ze źródeł zewnętrznych. Wszystko jest teraz dobre. –

1

Używam tego:

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

To szczególne opakowanie umożliwia łatwe słuchanie portu 0 (losowo wysokiego portu), które niektóre framugi zaciemniają. Automatycznie obsługuje żądania GET/POST dla wszystkich tras i łączy w argumenty URI z argumentami obiektu JSON najwyższego poziomu. W większości przypadków jest to wystarczająco dobre dla mnie.

Jest to o wiele lżejsza niż większość ram. Przypadki testowe w istocie pokazują lepiej, jak to działa.

Powiązane problemy