web-dev-qa-db-fra.com

Lecture de JSON à partir de données SimpleHTTPServer Post

J'essaie de créer un simple REST avec python SimpleHTTPServer. Je ne parviens pas à lire les données du message. Merci de me faire savoir si je le fais c'est juste.

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

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

SimpleJson ne parvient pas à charger le JSON à partir du message POST. Je ne suis pas familier avec le codage Web et je ne sais même pas si ce que je fais est correct pour créer un simple REST J'apprécie votre aide.

32
Guru Govindan

Merci matthewatabet pour l'idée de klein. J'ai imaginé un moyen de l'implémenter en utilisant BaseHTTPHandler. Le code ci-dessous.

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

Et la page html correspondante

<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>
44
Guru Govindan

SimpleHTTPRequestHandler ne prend pas en charge POST. C'est très simple en effet. Découvrez Klein dont le serveur est un peu plus complet.

Voici un exemple de json PUT (assez proche de POST) ici: https://pypi.python.org/pypi/klein/0.2.

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)
11
matthewatabet