0

I am very new to Flask and before i proceed further, is it possible to perform a "post" from jquery to python function using flask and json? I'm not familiar with json too and therefore all those codes seem very complicated to me.

For example:

from flask import Flask, jsonify, render_template, request
app = Flask(__name__)

@app.route('/_add_numbers')

how do I determine what to substitute /_add_numbers? I can't really find a good site to show me a simple tutorial or steps to do post with flask.

This is my current jQuery function:

$('#left_button').click(function(){
            $.post("cameraservo2.py", {direction:"left"}).done(function (reply) {
                $('#camerapos').empty().append(reply);
                alert("left button clicked");});

        });

Can I do this WITHOUT using the json??

yvonnezoe
  • 7,129
  • 8
  • 30
  • 47
  • 1
    What *exactly* are you trying to do? `HTTP POST` is used to transmit data *to* the server. Are you trying to get data *from* the server and display it or are you trying to push data to the server for processing? – msvalkon Feb 28 '14 at 07:59
  • @msvalkon I am trying to post/transmit the data as well as to display the return data, as asked in this post http://stackoverflow.com/questions/22087507/how-to-execute-python-function-from-jquery-post/22087585?noredirect=1#22087585 – yvonnezoe Feb 28 '14 at 08:24
  • @msvalkon i have just tried this example here https://github.com/mitsuhiko/flask/tree/master/examples/jqueryexample but failed. How do my html and javascript knows which python file i'm using? can't find it anywhere.... – yvonnezoe Feb 28 '14 at 08:25
  • You assume that saying `$.post('cameraservo2.py')` runs the python code in `cameraservo2.py`. That does *absolutely* not happen. – msvalkon Feb 28 '14 at 08:26
  • Well that happened with cherrypy... in fact i saw it quite frequently on the web where AJAX is used. However, i am sure flask doesn't like it :( nor do i like flask. – yvonnezoe Feb 28 '14 at 08:31

2 Answers2

4

$.post() doesn't use JSON. It sends a regular POST request, with application/x-www-form-urlencoded as the content type. In a Flask route this means that the fields you posted are found in the request.form object. If your view returns HTML you can insert it into your HTML document.

Just pick a route name that reflects what you want to do:

@app.route('/turn_servo', methods=['POST'])
def turn_servo_ajax():
    direction = request.form['direction']

    # do something with the direction value; it is a string
    if direction == 'left':
        # ...
    else:
        # ...

    return '<div>Turned the servo 50 degrees to the {}</div>'.format(direction)

You then use that route name in your $.post:

$('#left_button').click(function(){
            $.post("/turn_servo", {direction:"left"}).done(function (reply) {
                $('#camerapos').empty().append(reply);
                alert("left button clicked");});

        });
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • thanks! the "route" part is the confusing thing. How exactly do i know what to put at the place of `/turn_servo`? is it the function name in the jquery? – yvonnezoe Feb 28 '14 at 08:33
  • @yvonnezoe: No, it's the path portion of the request URL – Martijn Pieters Feb 28 '14 at 08:35
  • `/turn_servo` is the URL which you're going to handle (i.e `http://yourdomain.com/turn_servo`). You will still have to call some function in your `cameraservo2.py` to actually turn the camera, but this is the way how you will get the direction from the user. – msvalkon Feb 28 '14 at 08:36
  • just to clarify, my python file must be in the same directory as my html file right? And this statement `@app.route('/turn_servo', methods=['POST'])` has to be unique? Actually I still couldn't understand why does the jquery knows which python script to post to. :( – yvonnezoe Feb 28 '14 at 13:24
  • No, Flask is not a CGI script. Flask either needs to be running as a separate server or needs to integrate with an exiting server. See the [deployment options documentation](http://flask.readthedocs.org/en/latest/deploying/); there is a CGI option there but I'd *not* recommend using that. Instead, if you are new to Flask, I recommend you go through the tutorial in the documentation. Run a standalone development server and have it serve big your route and the HTML page. Don't try to fit into your existing webserver, not until you have the basics under your belt. – Martijn Pieters Feb 28 '14 at 13:52
  • sorry, i'm confused here. Where do i put this `turn_servo_ajax():` function? in my existing python script or another separate python script? – yvonnezoe Mar 03 '14 at 06:56
  • @yvonnezoe: Do you have a Flask server running? Do you understand how a Python Flask server works? I have the strong impression that you think this works like a regular CGI script; it doesn't. Once you have a Flask server running (start with the development server as outlined in the documentation) you can add routes to that server in the same file, or by using separate Python modules and importing. *This requires a minimum understanding of Python modules and importing*. – Martijn Pieters Mar 03 '14 at 10:45
  • yes i have done the routing part,just like the answer below. I run the Flask server `python routes.py` where routes.py contain the @app.route(). the server is running successfully but there still isn't any visible outcome. And I don't know which part goes wrong nor how to troubleshoot this problem. i have posted another question here: http://stackoverflow.com/questions/22141570/accessing-flask-server-from-my-web-page?noredirect=1#comment33597615_22141570 – yvonnezoe Mar 03 '14 at 11:47
1

I've copied the code from your original question to demonstrate how the above answer (Martijns) works with your code.

# Save this file as app.py
from flask import Flask, jsonify, render_template, request
from cameraservo2 import your_cam_function

app = Flask(__name__)

@app.route('/turn_servo', methods=['POST'])
def turn_servo_ajax():
    direction = request.form['direction']
    cam_result = your_cam_function(direction=direction)
    return '<div> {} </div>'.format(cam_result)   

if __name__ == '__main__':
    app.run(debug=True)


# This code is in cameraservo2.py and is imported above.
# I've simplified it to a function (not a member of a class).
# You have to work out how to use it in your context.
def your_cam_function(**data):
    import pigpio
    import time

    servos=4
    key = data['direction']

    m=1500
    while (m >= 500 and m <= 2500):
        if (key =="left"):
            m=m+100
        elif (key =="right"):
            m=m-100

    pigpio.start()

    pigpio.set_servo_pulsewidth(servos, m) 
    servostatus= "Servo {} {} micro pulses".format(servos[0], key, m)
    print servostatus
    time.sleep(1)

    pigpio.stop()

    return servostatus

Now when you do a POST request to /turn_servo and give it a direction: left, it will call the function from your cameraservo2.py. The turn_servo_ajax-function will return a piece of HTML to the user, <div>Servo x y micro pulses</div>.

Community
  • 1
  • 1
msvalkon
  • 11,887
  • 2
  • 42
  • 38
  • Thank you!! I will try it and let you know again :D thank you!! btw, does that mean i will have 2 python files? – yvonnezoe Feb 28 '14 at 13:19
  • where do I put `tun_servo_ajax` function? In cameraservo2.py or another python script? – yvonnezoe Mar 03 '14 at 06:59
  • @yvonnezone you put that in your flask application, whatever file manages your routing. It's typical for a flask application to have multiple files, please read through the [quickstart](http://flask.pocoo.org/docs/quickstart/) to see how to proceed. – msvalkon Mar 03 '14 at 07:22
  • I'm more confused now. I have flask installed but im not sure if i'm using the flask server. I have my index files and other python files in var/www/. the quickstart isnt very helpful though. I cant find my flask files. Do i have to start/initiate it first? – yvonnezoe Mar 03 '14 at 07:24
  • Or do i have to run the python file, say routes.py, which contains the `turn_servo_ajax()` function first? – yvonnezoe Mar 03 '14 at 07:26
  • Then how? :( the quickstart clearly didn't mention where to put that function nor give me a complete example script. please help me. :( thank you. – yvonnezoe Mar 03 '14 at 07:31
  • Sorry, I was typing the comment and pressed enter. I've updated my answer. Put the code above in their own files, run it and try to follow the quickstart. If you encounter further questions, please open up a new question on SO. – msvalkon Mar 03 '14 at 07:34
  • Thank you for your reply and help :) I copied those codes to a new file and run it in the terminal. I modified the last part to `app.run(host='0.0.0.0')` so that i can access it from another network computer. It says it is `running on http://0.0.0.0:5000 restarting with reloader`. But still nothing happen when i click the button. :( i think i will start a new question. – yvonnezoe Mar 03 '14 at 07:52