ofey
ofey

Reputation: 3347

Accessing a url in a Flask view

I am trying to access an external url https://data.dublinked.ie/cgi-bin/rtpi/realtimebusinformation?stopid=184&format=json in a Flask view

I get the error,

Not Found

The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.

Is that my local server that flask is looking for this url on. And if so why? I am running flask locally.

The view, services.py

from flask import Flask, Response
import json
import urllib2

app = Flask(__name__)

@app.route('/')
def test():
    return 'Everything is running!'

@app.route('/stopid')
def stopid():
    dublin_bus_url = "https://data.dublinked.ie/cgi-bin/rtpi/realtimebusinformation?stopid=184&format=json"
    response = urllib2.urlopen(dublin_bus_url)
    json_response = json.load(response)
    routes = set()
    for result in json_response["results"]:
        routes.add(result["route"])

    return json.dumps(list(routes))

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

The index.html and script is,

<!DOCTYPE html>
<html>
<head>
  <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
</head>
<body>
  <script>
    d3.json("/stopid", function(error, routes) {
      routes.forEach(function(route) {
        console.log(route)
      });
    });
  </script>
</body>
</html>

I am new to Flask but this must not be the way to deal with an external link in a view.

The code above is adopted from this excellent tutorial for the Donorschoose api.

https://youtu.be/bzl4hCH2CdY

https://github.com/VidyaSource/starting-with-data

Thanks,

Upvotes: 0

Views: 2958

Answers (1)

oxalorg
oxalorg

Reputation: 2798

If we assume that the HTML file is not being served by flask:

You need to enable Cross origin resource sharing. You can do this by creating a response and setting it's header Access-Control-Allow-Origin to *: that is everyone. Or you can set it to your own domain when deploying.

resp.headers['Access-Control-Allow-Origin'] = '*'

Also, you're calling d3.json("/stopid" ... you need to change this to:

d3.json("http://localhost:5000/stopid" ...

Complete code:

from flask import Flask, Response, jsonify
import json
import urllib2

app = Flask(__name__)

@app.route('/')
def test():
    return 'Everything is running!'

@app.route('/stopid')
def stopid():
    dublin_bus_url = "https://data.dublinked.ie/cgi-bin/rtpi/realtimebusinformation?stopid=184&format=json"
    my_response = urllib2.urlopen(dublin_bus_url)
    json_response = json.load(my_response)
    routes = set()
    for result in json_response["results"]:
        routes.add(result["route"])

    resp = jsonify(list(routes))
    resp.headers['Access-Control-Allow-Origin'] = '*'
    return resp

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

If the HTML is being served by flask, there is no need to enable cross origin sharing.

@app.route('/d3')
def d3():
    return render_template('d3.html')

Call the link to this url using:

d3.json("{{ url_for('stopid') }}", ...

But this isn't exactly reliable, because you don't want to use the api using javascript when you can do it in flask itself.

Upvotes: 1

Related Questions