Search code examples
pythonajaxrestsimplejsonsimplehttpserver

Reading JSON from SimpleHTTPServer Post data


I am trying to build a simple REST server with python SimpleHTTPServer. I am having problem reading data from the post message. Please let me know if I am doing it right.

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

The index.html file

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

The SimpleJson fails to load the json from the POST message. I am not familiar with web coding and I am not even sure if what I am doing is right for creating a simple REST API server. I appreciate your help.


Solution

  • Thanks matthewatabet for the klein idea. I figured a way to implement it using BaseHTTPHandler. The code below.

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

    And the corresponding html page

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