How to call a python script with ajax in cherrypy app
Question: I am trying to get the output from a python script and put it into a table in
the html of my cherrypy app.

Example app:

    
    
    import string, os
    import cherrypy
    
    file_path = os.getcwd()
    
    html = """<head>
    <meta content="text/html; charset=ISO-8859-1"
    http-equiv="content-type">
    <title>CCMF</title>
    <link rel='shortcut icon' type='image/x-icon' href='img/favicon.ico' />
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
    
    <script>
        function b1() {
            var request = $.ajax({
                url: "b1.py",
                type: "POST",            
                dataType: "text"
            });
            request.done(function(msg) {
                $("#output").html(msg);          
            });
            request.fail(function(jqXHR, textStatus) {
                alert( "Request failed: " + textStatus );
            });
        }
    </script>
    
    </head>
    <button onclick="b1()">call b1.py</button>
    ...
    <td id = "output"; style="vertical-align: top; height: 90%; width: 100%;">
    <--output goes here -->
    </td>
    ...
    </html>
    """
    class ccmf(object):
    
        @cherrypy.expose
        def index(self):
        return html
    
    if __name__ == '__main__':
        cherrypy.server.socket_host = "127.0.0.1"
        cherrypy.server.socket_port = 8084
        config = {
             "/img": {
                 "tools.staticdir.on": True,
                 "tools.staticdir.dir": os.path.join(file_path, "img"),
             }
        }
        cherrypy.tree.mount(ccmf(), "/", config=config)
        cherrypy.engine.start()
        cherrypy.engine.block()
    

and here's the example python script b1.py:

    
    
    def b1():
        op = "ajax b1 pushed"
        print op
        return op
    
    b1()
    

The ajax get's called but returns the failure alert. I have tried GET, POST,
"text", "html", b1.py is in the same directory, no joy. All currently running
on my local box.

Any hints greatly appreciated!


Answer: You are completely misunderstanding how modern, CherryPy's for instance,
routing works. Unlike outdated approaches that were commonly employed with CGI
and Apache's mod_* (mod_php, mod_python, etc.), where you directly point to
the file containing the script with URL, modern routing is an application
level activity.

Your application receives all requests and dispatches them according to the
established method. CherryPy in that sense has two major approaches: [built-in
object tree
dispatcher](https://cherrypy.readthedocs.org/en/3.2.6/concepts/dispatching.html#default-
dispatcher) and [Routes
adapter](https://cherrypy.readthedocs.org/en/3.2.6/concepts/dispatching.html#other-
dispatchers). For most simple and mid-level cases built-in dispatcher is fair
enough.

Basically it can look like this.

_app.py_

    
    
    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    
    
    import os
    
    import cherrypy
    from cherrypy.lib.static import serve_file
    
    
    path   = os.path.abspath(os.path.dirname(__file__))
    config = {
      'global' : {
        'server.socket_host' : '127.0.0.1',
        'server.socket_port' : 8080,
        'server.thread_pool' : 8
      }
    }
    
    class App:
    
      @cherrypy.expose
      def index(self):
        return serve_file(os.path.join(path, 'index.html')) 
    
      @cherrypy.expose
      @cherrypy.tools.json_out()
      def getData(self):
        return {
          'foo' : 'bar',
          'baz' : 'another one'
        }
    
    
    if __name__ == '__main__':
      cherrypy.quickstart(App(), '/', config)
    

_index.html_

    
    
    <!DOCTYPE html>
    <html>
    <head>
    <meta http-equiv='content-type' content='text/html; charset=utf-8'>
    <title>CCMF</title>
    <script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js'></script>
    <script type='text/javascript'>
      $(document).ready(function()
      {
        $('button').on('click', function()
        {
          var request = $.ajax({'url': '/getData'});
          request.done(function(response) 
          {
            $('#foo').text(response.foo);
            $('#baz').text(response.baz);
          });
          request.fail(function(jqXHR, textStatus) 
          {
            alert('Request failed: ' + textStatus);
          });
        })
      });
    </script>
    </head>
    <body>
      <button>make ajax call</button>
      <h1>Foo</h1>
      <div id='foo'></div>
      <h1>Baz</h1>
      <div id='baz'></div>
    </body>
    </html>
    

Here's [the runnable](http://runnable.com/VAbwozeDTpkHhLoJ/how-to-call-a-
python-script-with-ajax-in-cherrypy-app-for-stackoverflow) just in case.

