Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Loading Data Asynchronously in Python/Flask for d3.js

I have a python/flask application. In it I have a page which queries the database a lot in order to display the data on the page. However, if I include this logic in the view.py where the @app.route() is, then loading the page takes too long. I'm then displaying this data with d3.

My current setup is that I have a separate route from the view which calculates the data (let's say "/data" is the path). When you go to that path, it returns the data in a json format and is loaded by

d3.json("/data", callback)

This works fine. My issue is that there are a lot of different queries I need to complete, and having a different path for each dataset is cluttering up my app and doesn't seem to be following the DRY principle. Is there a better way to do this? I'm also having difficulties passing variables to the javascript that runs the d3 from python.

like image 455
kevin.w.johnson Avatar asked May 22 '14 15:05

kevin.w.johnson


People also ask

Why should developers learn flask and D3?

This is why developers should understand how to build programs that enable easy data visualization. Flask is a Python web framework that provides the tools, libraries, and technologies required to build web applications. D3.js is a JavaScript library that manipulates DOM elements using data to render visual components.

Is flask a good framework to learn Python?

Likewise, Flask is beginner-friendly and you can develop simple Flask web apps based on your fundamental knowledge of Python. Both frameworks have a huge community of developers who are actively improving the libraries and may be able to provide help if needed.

How to load a JSON file using D3?

Create a sample file "users.json" in the data folder of your project's root folder and paste the following JSON in it. Now, load the above JSON file using d3.json () as shown below.

How to check if D3 data got loaded successfully?

While loading data from an external source, D3 returns an argument called "error". You can use this argument to check whether your data got loaded successfully. If there is some error while loading your data, say your data is malformed; D3 will return an error object.


1 Answers

What you really need here is an API for accessing the data. If you're using flask already then Flask-Restful is a great option. You can set up a route like this:

from flask import Flask
from flask_restful import Resource, Api, reqparse

app = Flask(__name__)
api = Api(app)

class Data(Resource):
    def __init__(self):
        self.parser = reqparse.RequestParser()
        self.parser.add_argument('name', type=str, required = True)
        self.parser.add_argument('whatever', type=str, required = True)
    def post(self):
        args = self.parser.parse_args()
        #query your database here and do your stuff
        print(args['name'])
        print(args['whatever'])
        return {'data': 'your data here',
                'other_information': 'more_stuff' }
api.add_resource(Data, '/data')

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

and then you'll be able to pass variables that specify what data is needed to using either JSON, query strings, or a form. Flask-Restful is pretty smart and will figure out the method that you're using to send it automatically. Then you can return a dictionary which will be encoded using JSON. This should address your second issue of passing multiple variables back to the javascript.

An example of the corresponding javascript is here:

var xhr = new XMLHttpRequest();
xhr.open("POST", "http://127.0.0.1:5000/data");
xhr.setRequestHeader('Content-Type', 'application/json;charset=UTF-8');
xhr.onload = function() {
    var dict = JSON.parse(xhr.responseText);
    console.log(dict['data']);
    console.log(dict['other_information']);
};

var request = JSON.stringify({'name':'my_name', 'whatever':'stuff'});
xhr.send(request);
like image 108
Ivanna Avatar answered Oct 05 '22 08:10

Ivanna