Search code examples
javascriptpythonhtmlxmlhttprequestcgi

How do I call a python function from a cgi script with javascript?


I also want to use the XMLHttpRequest object in a javascript function to send info about the currently selected option from a dropdown list (the one called 'Users' in the code below) as an argument to a function in my Python script, and then get the return value from that function and use it to setup another list ('Tasks' in the code below) I want to do this so that I can update the information in "Tasks" using data that I have gotten as a return value from the Python function I am doing it this way because I need the page to not have to reload. If you know a better way to implement this I would be open to ideas.

def main():
with open("Users.json", 'r') as data_file:
    usersDictionary = json.load(data_file)
Users=usersDictionary["Users"]
print "Content-Type: text/html"
print ""
print """
<html>
<head>
    <script>
      function setTaskList(){
          #Insert Javascript which will call python function here...
      }
        </script>
        <title>TestPage</title>
    </head>
    <body onload="setTaskList()">
        <form>"""
print """<select name="Users" onchange="setTaskList()">"""
for user in Users:
    if(not(len(user["Tasks"]["High"])==0 and len(user["Tasks"]["Med"])==0 and len(user["Tasks"]["Low"])==0)):
        print """<option value="{0}">{1}</option>""".format(user["UID"], user["name"])
print "</select>"
print """<select name="Tasks" disabled="disabled">"""
print "</select>"
print"""<input type="Submit" value="Add Task"/>
<button type="button">Delete Task</button>"""
print"""
        </form>
</body>
</html>"""

main()

For the code below, I want to be able to get the data from input boxes when submit is clicked, and send the info gotten from the input boxes and radio buttons to a python function to process it and add it as a JSON object to a JSON dictionary and then update a JSON file, and then return to the previous page (which is the one with the code above) (assume that is called index.py).

print "Content-Type: text/html"
print ""
print"""<html>
<head>
    <title>Title</title>
</head>
<body>
    <form  action = "/~theUser/cgi-bin/index.cgi" method = "POST">
        Task Name:   <input type = "text" name = "TaskName" 
placeholder="Task name" />  <br />
        Task Description:    <input type = "text" name = "TaskDescription" 
placeholder="task description" /> <br />
        User ID:    <input type = "text" name = "UID" placeholder="User Id" 
/> <br />
        Priority <br/>
        <input type="radio" name="gender" value="High"> High<br>
        <input type="radio" name="gender" value="Medium"> Medium<br>
        <input type="radio" name="gender" value="Low"> Low<br>
        <input type = "submit" value = "Submit" />
    </form>
</body>
</html>"""

Can anyone help, I'm really new to this CGI stuff, and would really appreciate it. Also if you know a better for me to do this, please let me know. Thanks!


Solution

  • So after long trial and error, and waiting on an answer that never came, I figured out how to do this myself so I thought I might help whoever was in need of this out I was able to send a request from my python cgi script using javascript like so:

    print "Content-Type: text/html"
    print ""
    print """
    <html>
    <head>
        <script>
        function getTasks() { 
           //put more processing in the function as needed
           var xmlhttp;
           var parameters = "This must be a string which will be the parameters 
           you will receive in your python script";
           var scriptName = "pythonScript To CommunicateWith.py";
           //may be .cgi as well depending on how you are using it
           if (window.XMLHttpRequest) {
               xmlhttp = new XMLHttpRequest();
            } else {
                 xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
            }
            xmlhttp.open("POST", scriptName, true);
            xmlhttp.onreadystatechange = function () {
                if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
                    //retrieve a json response and parse it into userTasks
                    usersTasks = JSON.parse(xmlhttp.responseText);
                 }
            }
            xmlhttp.send(parameters);
         }
        </script>
    

    In my python script which the java script hits here is how I get the arguments and process them:

    #!usr/bin/python
    import sys
    import json
    
    args=sys.stdin.readlines() #args comes in as a list with one item in it 
    which is the parameter that you sent in from javascript
    
    arguments=args[0]
    print "Content-Type: text/html"
    print ""
    
    def getTasks(userName):
        """This function will do some processing and get the required return 
        value"""
        taskList=[]
        #read JSON file and get the info.
        with open("Somefile.json", 'r') as data_file:
            usersDictionary = json.load(data_file)
        data_file.close()
        """...do some process ing of data here, which will set some data into 
        the list called taskList"""
        return taskList #Return a list of all the tasks for the user.
    
    print json.dumps(getTasks(arguments)) 
    """convert the json to a string and print it out. what you print out here 
    will be what you will get as a string in the .responseText of the 
    XMLHttpRequest 
    object"""
    

    Using Pycharm and the python CGIHTTPServer function to debug helped me here. Hope this helps someone out there.