0

I'd appreciate some help with something I'm working on for my final project. I'm trying to create a web-app based on what we had to do for Pset8 - creating a google map that updates with information accessed via API.

In my case, I've created a database of all of the solar PV installations in the UK and have them appearing on a google map. I now want to access information from other sources that I can display on the web-app, specifically:

(i) forecast UK-wide electricity generation from solar PV - via an API provided by sheffield university; and (ii) weather forecast information for each site - which I aim to get via an API provided by the UK meteorological office.

I'm working on the first of these at the moment.

Sheffield university provides information on its API at https://docs.google.com/document/d/1ReskTA8ifkYnHv2j9-GC-BmuB7G4wmM-QMwlZi77218/pub

They provide an example of python code to use:

sheffield university example code

When I try this in a simple python file it works fine - returns exactly what the API's documentation says it will:

enter image description here

So I've created a route in my python file application.py using this code:

@app.route("/sheffield")
def sheffield():
    """Get data from Sheffield Solar API"""
    """See: https://www.solar.sheffield.ac.uk/pvlive/api/"""

    # define class Querier - to use with Sheffield Solar API. See:
    # https://docs.google.com/document/d/1ReskTA8ifkYnHv2j9-GC-BmuB7G4wmM-QMwlZi77218/pub#h.1qzzbmhxk371
    class Querier(object):
        def __init__(self, url_base, username, password):
            self.url_base=url_base
            self.username=username
            self.password=password
        def query(self, substation_id):
            return requests.get(self.url_base + str(substation_id), auth=requests.auth.HTTPBasicAuth(self.username, self.password))

    if __name__ == '__main__':
        url_base='https://www.solar.sheffield.ac.uk/ssfdb3/crud' / 
        'nationalgrid/pvnowcast/'
        username='pvlive'
        password=''     #2 single quotes i.e. empty string
        querier = Querier(url_base, username, password)
        substation_id=0
        response = querier.query(substation_id)
        print(response.text)
        return response

Then, in my scripts.js file, I call the function sheffield() as part of configuring the google map - in very much the same way as I call the update() function (from pset8):

/**
* Configures application.
*/
function configure()
{
   // update UI after map has been dragged
   google.maps.event.addListener(map, "dragend", function() {

        // if info window isn't open
        // http://stackoverflow.com/a/12410385
        if (!info.getMap || !info.getMap())
        {
            sheffield();
            update();
        }
    });

    // update UI after zoom level changes
    google.maps.event.addListener(map, "zoom_changed", function() {
        sheffield();
        update();
    });

    // configure typeahead
    $("#q").typeahead({
        highlight: false,
        minLength: 1
    },
    {
        display: function(suggestion) { return null; },
        limit: 1000,
        source: search,
        templates: {
            suggestion: Handlebars.compile(
                "<div>"+
                "{{Site_Name}}, {{County}}, {{Post_Code}}"+
                "</div>"
            )
        }
    });

    // re-center map after place is selected from drop-down
    $("#q").on("typeahead:selected", function(eventObject, suggestion, name) {

        // set map's center
        map.setCenter({lat: parseFloat(suggestion.Lat), lng: parseFloat(suggestion.Long)});

        // update UI
        sheffield();
        update();
    });

    // hide info window when text box has focus
    $("#q").focus(function(eventData) {
        info.close();
    });

    // update UI
    sheffield();
    update();

    // give focus to text box
    $("#q").focus();
}

What I expected was this:

  • The map instantiates and plots all of my locations on the map. Tick! This works.

  • scripts.js calls the "update" route. Tick! This works.

  • scripts.js calls the "sheffield" route in application.py and this (i) prints the json output to the terminal, and (ii) returns a json. (NB I know I'm not doing anything with this JSON right now - step by step!) This fails.

I get the following error message, which I think is telling me that Flask is returning a None-type when I call the "sheffield" route:

error message

I'd really appreciate your help! Thanks, Matt

1 Answer 1

0

The answer appears to be that my route (@app.route("sheffield") returns a dict - but Flask doesn't allow dicts as a return type from this kind of function - see the documentation for Response objects : http://flask.pocoo.org/docs/0.12/api/#flask.Response

So I changed the code to finish as follows:

response = querier.query(substation_id)
response_transformed = response.text
return response_transformed

The object is now callable and can be read/accessed by my javascript. All I need to do now is solve the mysteries of asynchronous calls...!

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .