How to implement a minimal server for AJAX in Python?

前端 未结 4 1985
既然无缘
既然无缘 2020-11-27 09:45

I want to create a very simple HTML/AJAX based GUI for a Python program. So the frontend is a HTML page which communicates with the program via AJAX. Can you give me a minim

4条回答
  •  谎友^
    谎友^ (楼主)
    2020-11-27 10:10

    O.K., I think I can now answer my own question. Here is an example implementation for calculating the square of a number on the server. Please let me know if there are any improvements or misconceptions.

    the python server file:

    import threading
    import webbrowser
    import BaseHTTPServer
    import SimpleHTTPServer
    
    FILE = 'frontend.html'
    PORT = 8080
    
    
    class TestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
        """The test example handler."""
    
        def do_POST(self):
            """Handle a post request by returning the square of the number."""
            length = int(self.headers.getheader('content-length'))        
            data_string = self.rfile.read(length)
            try:
                result = int(data_string) ** 2
            except:
                result = 'error'
            self.wfile.write(result)
    
    
    def open_browser():
        """Start a browser after waiting for half a second."""
        def _open_browser():
            webbrowser.open('http://localhost:%s/%s' % (PORT, FILE))
        thread = threading.Timer(0.5, _open_browser)
        thread.start()
    
    def start_server():
        """Start the server."""
        server_address = ("", PORT)
        server = BaseHTTPServer.HTTPServer(server_address, TestHandler)
        server.serve_forever()
    
    if __name__ == "__main__":
        open_browser()
        start_server()
    

    ...and the HTML file (I call it 'frontend.html', unfortunately the name has to appear in the JavaScript code as well):

    
    
    AJAX test
    
    
    
    
    
    sqr( ) = 0

    Of course it would be much more convenient to use jQuery for the XML request, but in the interest of simplicity I'll leave it like that.

    Finally an alternative implementation using WSGI (unfortunately I didn't see a way to fall back on the standard file-serving handler if the request is not a POST):

    import threading
    import webbrowser
    from wsgiref.simple_server import make_server
    
    FILE = 'frontend.html'
    PORT = 8080
    
    def test_app(environ, start_response):
        if environ['REQUEST_METHOD'] == 'POST':
            try:
                request_body_size = int(environ['CONTENT_LENGTH'])
                request_body = environ['wsgi.input'].read(request_body_size)
            except (TypeError, ValueError):
                request_body = "0"
            try:
                response_body = str(int(request_body) ** 2)
            except:
                response_body = "error"
            status = '200 OK'
            headers = [('Content-type', 'text/plain')]
            start_response(status, headers)
            return [response_body]
        else:
            response_body = open(FILE).read()
            status = '200 OK'
            headers = [('Content-type', 'text/html'),
                       ('Content-Length', str(len(response_body)))]
            start_response(status, headers)
            return [response_body]
    
    def open_browser():
        """Start a browser after waiting for half a second."""
        def _open_browser():
            webbrowser.open('http://localhost:%s/%s' % (PORT, FILE))
        thread = threading.Timer(0.5, _open_browser)
        thread.start()
    
    def start_server():
        """Start the server."""
        httpd = make_server("", PORT, test_app)
        httpd.serve_forever()
    
    if __name__ == "__main__":
        open_browser()
        start_server()
    

提交回复
热议问题