Reputation: 3347
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://github.com/VidyaSource/starting-with-data
Thanks,
Upvotes: 0
Views: 2958
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