2014年1月9日木曜日

How do we give objects from the server to the client-side? python.flask

related to Python, Flask, JQuery, Javascript.

this image is created by keyart (http://nktyasu.dip.jp/keyart)
This image is created by keyart (http://nktyasu.dip.jp/keyart)

When you make a web application, you may face this problem. In the most of applications, the server gives objects to client-side (like javascript). In this article, I’d like to show a way using JSON.
Note that we use Python and Flask, but you can apply this any other Programming languages and frameworks.

Making API

First, you should make your own API (Application Programming Interface). Sample code is like this:

from flask import Flask
import json
app = Flask(__name__)

@app.route("/get_data")
def get_data():
    data = [{"firstname": "hiroyuki", "lastname": "tanaka"},
            {"firstname": "John", "lastname": "Smith"}]
    return json.dumps({"data": data})

The get_data method return a JSON object as a text. Let’s run the development server:

$ python demo.py

and access to localhost:5000/get_data. you will see the object. Now you are ready for getting objects.

Call the API from client-side using Ajax

This is the key of this article. Since your API gives the client objects, your client have to receive the objects. To do this, we use Ajax. Sample code is like this:

$(function(){
    var data;
    $.ajax({
        type: "GET",
        url: $SCRIPT_ROOT + "/get_data",
        dataType: "json",
        timeout: 120000,
        error: errorHandlier,
        success: function(r){
            data = r.data;
        }
    });
    setTimeout(function(){
        if(data != null){
            /* whatever you want to do using the results */
            /* For example using above API, */ 
            alert("Hello "+data[0].firstname+" "+data[0].lastname);
        }
        else{
            setTimeout(arguments.callee, 100);
        }
    }
});

And you have to set $SCRIPT_ROOT in your html file like this:

<script> $SCRIPT_ROOT = {{ request.script_root|tojson|safe }}; </script>

As you can see in the code, we should use setTimeout method to wait until loading the object completely since The $.ajax method is asynchronous.

That’s it. In the rest of article, I want to discuss about how to give objects from the server to client.

Discussion

using template engine ( flask.render_template)

Flask uses powerful template engine (jinja2?). You can give objects using this. the server side script is like this:

from flask import Flask, render_template
import json
app = Flask(__name__)

@app.route("/get_data")
def get_data():
    data = [{"firstname": "hiroyuki", "lastname": "tanaka"},
            {"firstname": "John", "lastname": "Smith"}]
    return render_template("index.html", data=json.dumps({"data": data}))

and index.html is like this:

<html>
<head>
<script> data = {{data|safe}} </script>
</head>

That’s it. This is very easy. I used to use this. But users can see the objects. So if you don’t matter that users can see the objects, you use this way.

using $.getJson method

You can use $.getJson method instead of $.ajax method like this:

var data
    $.getJSON($SCRIPT_ROOT+"/get_data", function(r){
            data = r.data;
    });

But, when I tried this, it doesn’t work well on iPhone Safari.

Any suggestions?

Thank you for reading this article. I mentioned how we give obejcts from the server to client. But I’m almost new about web development. If you have more useful and clever way, Please let me know.

Written with StackEdit.

make_response

Vukasin-san proposed a better way using make_response. Thanks for helping^^.
I wrote sample code like this:

from flask import Flask, make_response
import ujson
app = Flask(__name__)

@app.route("/get_objects")
def get_objects():
    data = [{"firstname": "hiroyuki", "lastname": "tanaka"},
            {"firstname": "John", "lastname": "Smith"}]
    response = make_response()
    response.headers["Content-Type"] = "application/json"
    response.status_code = 200
    response.data = {"data": ujson.dumps(data)}
    return response

0 件のコメント:

コメントを投稿