2015-07-12 10 views
27

Sto cercando di creare un semplice server REST con Python SimpleHTTPServer. Sto avendo problemi a leggere i dati dal messaggio postale. Per favore fatemi sapere se lo sto facendo bene.Lettura JSON da SimpleHTTPServer Dati post

from SimpleHTTPServer import SimpleHTTPRequestHandler 
import SocketServer 
import simplejson 

class S(SimpleHTTPRequestHandler): 
    def _set_headers(self): 
     self.send_response(200) 
     self.send_header('Content-type', 'text/html') 
     self.end_headers() 

    def do_GET(self): 
     print "got get request %s" % (self.path) 
     if self.path == '/': 
      self.path = '/index.html' 
      return SimpleHTTPRequestHandler.do_GET(self) 

    def do_POST(self): 
     print "got post!!" 
     content_len = int(self.headers.getheader('content-length', 0)) 
     post_body = self.rfile.read(content_len) 
     test_data = simplejson.loads(post_body) 
     print "post_body(%s)" % (test_data) 
     return SimpleHTTPRequestHandler.do_POST(self) 

def run(handler_class=S, port=80): 
    httpd = SocketServer.TCPServer(("", port), handler_class) 
    print 'Starting httpd...' 
    httpd.serve_forever() 

Il file index.html

<html> 
<title>JSON TEST PAGE</title> 
<head> 
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> 
<script type="text/javascript"> 

JSONTest = function() { 

var resultDiv = $("#resultDivContainer"); 

$.ajax({ 
    url: "http://128.107.138.51:8080", 
    type: "POST", 
    data: {txt1: $("#json_text").val()}, 
    dataType: "json", 
    success: function (result) { 
     switch (result) { 
      case true: 
       processResponse(result); 
       break; 
      default: 
       resultDiv.html(result); 
     } 
    }, 
    error: function (xhr, ajaxOptions, thrownError) { 
    alert(xhr.status); 
    alert(thrownError); 
    } 
}); 
}; 

</script> 
</head> 
<body> 

<h1>My Web Page</h1> 
<div id="resultDivContainer"></div> 
<form> 
<textarea name="json_text" id="json_text" rows="50" cols="80"> 
[{"resources": {"dut": "any_ts", "endpoint1": "endpoint", "endpoint2": "endpoint"}}, 
{"action": "create_conference", "serverName": "dut", "confName": "GURU_TEST"}] 
</textarea> 
<button type="button" onclick="JSONTest()">Generate Test</button> 
</form> 
</body> 
</html> 

La simplejson non riesce a caricare il JSON dal messaggio POST. Non ho familiarità con la codifica Web e non sono nemmeno sicuro se quello che sto facendo è giusto per creare un semplice server API REST. Apprezzo il tuo aiuto.

+1

Inoltre si prega di farmi sapere se questa non è la strada da percorrere e se avere un Django è l'unico modo per andare. –

risposta

32

Grazie matthewatabet per l'idea Klein. Ho trovato un modo per implementarlo usando BaseHTTPHandler. Il codice qui sotto

from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer 
import SocketServer 
import simplejson 
import random 

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

    def do_GET(self): 
     self._set_headers() 
     f = open("index.html", "r") 
     self.wfile.write(f.read()) 

    def do_HEAD(self): 
     self._set_headers() 

    def do_POST(self): 
     self._set_headers() 
     print "in post method" 
     self.data_string = self.rfile.read(int(self.headers['Content-Length'])) 

     self.send_response(200) 
     self.end_headers() 

     data = simplejson.loads(self.data_string) 
     with open("test123456.json", "w") as outfile: 
      simplejson.dump(data, outfile) 
     print "{}".format(data) 
     f = open("for_presen.py") 
     self.wfile.write(f.read()) 
     return 


def run(server_class=HTTPServer, handler_class=S, port=80): 
    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() 

e la corrispondente pagina HTML

<form action="/profile/index/sendmessage" method="post" enctype="application/x-www-form-urlencoded"> 
<div class="upload_form"> 
    <dt id="message-label"><label class="optional" for="message">Enter Message</label></dt> 
    <dd id="message-element"> 
    <textarea cols="80" rows="50" id="message" name="message"> 
[{"resources": {"dut": "any_ts", "endpoint1": "multistream_endpoint", "endpoint2": "multistream_endpoint"}}, 

{"action": "create_conference", "serverName": "dut", "conferenceName": "GURU_SLAVE_TS"}, 

{"action": "dial_out_ep", "serverName": "dut", "confName": "GURU_SLAVE_TS", "epName": "endpoint1"} 
] 
     </textarea></dd> 
    <dt id="id-label">&nbsp;</dt> 
    <dd id="id-element"> 
    <input type="hidden" id="id" value="145198" name="id"></dd> 
    <dt id="send_message-label">&nbsp;</dt> 
    <dd id="send_message-element"> 
    <input type="submit" class="sendamessage" value="Send" id="send_message" name="send_message"></dd> 
</div> 
</form> 

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> 
<script type="text/javascript"> 
$("input.sendamessage").click(function(event) { 
event.preventDefault(); 

var message = $('textarea#message').val(); 
var id  = $('input#id').val(); 
url = "http://128.107.138.51:8080" 

var posting = $.post(url, message) 

posting.done(function(data) { 
    alert(message); 
}); 
}); 


</script> 
8

SimpleHTTPRequestHandler non supporta il POST. È davvero molto semplice. Dai un'occhiata a Klein, il cui server è un po 'più completo.

C'è un esempio di un PUT JSON (abbastanza vicino a POST) qui: https://pypi.python.org/pypi/klein/0.2.3

import json 

from klein import Klein 


class ItemStore(object): 
    app = Klein() 

    def __init__(self): 
     self._items = {} 

    @app.route('/') 
    def items(self, request): 
     request.setHeader('Content-Type', 'application/json') 
     return json.dumps(self._items) 

    @app.route('/<string:name>', methods=['PUT']) 
    def save_item(self, request, name): 
     request.setHeader('Content-Type', 'application/json') 
     body = json.loads(request.content.read()) 
     self._items[name] = body 
     return json.dumps({'success': True}) 

    @app.route('/<string:name>', methods=['GET']) 
    def get_item(self, request, name): 
     request.setHeader('Content-Type', 'application/json') 
     return json.dumps(self._items.get(name)) 


if __name__ == '__main__': 
    store = ItemStore() 
    store.app.run('localhost', 8080) 
+0

Grazie per il link. Ho anche pensato che potesse essere fatto con BaseHTTPHandler. –