I am working on flask + Angular + MongoDb application. I am using state provider in angular. states are loading perfectly fine from application. but when i refresh the page it is throwing 404 error.
App.py: (Flask)
application = Flask(__name__)
#application.route('/')
def showMachineList():
print ("Inside the show machine list function")
return application.make_response(open('templates/index.html').read())
App.js ( Angular)
angular.module('testapp', ['ngCookies', 'ngResource',
'ngSanitize', 'ui.router', 'ui.bootstrap','ngMaterial','ngCookies'
])
.config(function($urlRouterProvider, $locationProvider,$interpolateProvider) {
$urlRouterProvider.otherwise('/');
//$interpolateProvider.startSymbol('//').endSymbol('//');
$locationProvider.html5Mode(true).hashPrefix('!');
});
State
angular.module('testapp')
.config(function ($stateProvider) {
console.log("inside create outage request")
$stateProvider
.state('cor', {
url: '/cor',
template: '<cor></cor>'
//templateUrl: '/static/client/app/acn/acn.html'
});
});
I have added the <base href="/"> in index.html as well.
when i refresh the page with "http://localhost:5000/cor" its throwing 404.
Can you let me know what i am missing?
This is fairly common problem with Single Page Applications. Looks like your Angular app can handle the cor state properly on the client-side, but your web server has no way to know that the /cor path should be routed to the same Angular application on the initial load.
Try adding a second route to your endpoint:
#application.route('/')
#application.route('/cor')
def showMachineList():
...
Alternatively, you could use a catch-all route to handle any path suffix.
When you refresh the page the browser send the URL "http://localhost:5000/cor" to the server. As I can see in your code, there's no /cor route defined, only /. I think you have to define one.
#application.route('/cor')
def showMachineList():
with open('templates/index.html') as fd:
content = fd.read()
return application.make_response(content)
The problem may be in your template: the one where you define the link to cor. You should have something like this:
link to cor
I make the assumption that you have written this instead:
link to cor
Related
I am trying to get a webpage to update from an API endpoint whenever that endpoint updates. Right now my webpage works if I refresh it but I want it to update automatically.
import json
import requests
from flask import Flask, render_template
app = Flask(__name__)
s = requests.session()
# API Key
s.headers.update({'Authorization': 'apikeygoeshere'})
#app.route("/")
def index():
alarms = s.get('https://site/api/alarms')
alarmData = json.loads(alarms.text)
if next in alarmData:
while alarmData['next']:
nextUrl = alarmData['next']['href']
print(nextUrl)
nextUrlGet = s.get(nextUrl)
nextData = json.loads(nextUrlGet.text)
alarmData = nextData
if not alarmData['next']:
break
else:
print('No Next -> Update Ready')
alarmUpdateUrl = alarmData['updates']['href']
update = s.get(alarmUpdateUrl)
updateData = json.loads(update.text)
if not updateData['updates']:
updateName = "Nothing"
else:
updateName = updateData['updates'][0]['source']['name']
alarmUpdateUrl = updateData['next']['href']
print(alarmUpdateUrl)
s.get(alarmUpdateUrl)
return render_template('index.html', data=updateName, url=alarmUpdateUrl)
if __name__ == '__main__':
app.run(debug=True, threaded=True)
I tried putting the code in a while loop but it didn't seem to restart. Esentially the endpoint may not have an updates url on page one so i have to follow the next link until there is an update href then request that to initiate a long poll.
When you call an endpoint, Flask figures out which method to run, runs this method, and returns a response, in your case HTML. The connection between client (your browser) and server is then terminated and flask stops doing anything (more or less) until a new request comes in. If you want a website to refresh automatically, you have a few options, but all of them have to be implemented on the client side:
Add <meta http-equiv="refresh" content="30">
to your html head in index html. This will cause your browser to reload the page every 30 seconds.
Add some javascript to your index.html which will poll your API endpoint and update your page when new information is available.
Use websockets (this is similar to the pure javascript approach but potentially with less polling).
I am working on a project and am relatively new to flask. I have a python script that outputs a data frame and this all works fine with my HTML code. The issue I am having is that I need to reroute to an external link. My flask code works fine if I output a link to a site such as variable = "www.google.com" but it does to work correctly with variable = prediction['Link'][0]. I get http://127.0.0.1:5000/stringOutputofPrediction instead of http://stringOutputofPrediction Any help would be greatly appreciated as I have been banging my head against the wall for a couple of hours now.
Here is my html code:
<div class="inner">
<h3>{{prediction['Episode'][0]}}</h3>
<p>{{prediction['Description'][0]}}</p>
<a href= "{{ url_for('go_outside_flask_method', variable = prediction['Link'][0]) }}" >Watch</a>
</div>
Flask/Python Script:
#app.route('/<string:variable>',)
def go_outside_flask_method(variable):
variable = 'https://'+ variable
return redirect(variable, code = 307)
In this case, I would do something like this
from flask import Flask, render_template, redirect, request
app = Flask(__name__)
#app.route('/')
def index():
return render_template('index.html')
#app.route('/redirect_to')
def redirect_to():
link = request.args.get('link', '/')
new_link = 'http://' + link
return redirect(new_link), 301
Notice, that I do not expect the link in my link, I expect it in the request.args where I extract it and redirect client to a new link that is outside of the flask application. Also if the link is not provided, then I redirect to the index page.
And the HTML would be like this
<html>
<body>
Redirect me to
</body>
</html>
P.s. you should make sure that your variable = prediction['Link'][0]) is really what you expect stringOutputofPrediction, try to debug when getting variable/link to the back-end redirect_to route.
When using Angular 5 with Flask and ng build --aot --watch, I am having major issues getting Angular's routing and refreshing the page to work.
I have come across many attempts to fix this, but none of them when applied to my project work (and the example projects provided when I try it there also do not seem to work).
What happens (depending on the thing I try) are these:
It can't find the path at all and I get a Jinja2 error
It can't find the document for localhost:5015/ (the port I'm using) and I get a 404 and a white screen
It loads index.html, but upon refresh it gets a 404 (implying that the browser is attempting to fetch the page from the server, not using the Angular routing system)
I get the same issue as this one: Syntax Error in Angular App: Unexpected token <
I am under the impression this is a normal issue with all SPAs and that the solution is to always redirect the server to index.html. We have done this (AFAIK), and attempted multiple ways to do this:
Our structure is roughly the following:
- ProjectDir
- reverseProxy_Calls
- scripts
- swagger_yaml_definitions
- templates
- e2e
- dist
- src
- app
And our server.py contains this (among other stuff)
Swagger(app)
app.template_folder = "./templates/dist/"
app.static_folder = "./templates/dist/"
app.static_path = "./templates/dist/"
app.static_url_path = "./templates/dist/"
app.instance_path = "./templates/dist/"
config = settings.config()
config.read("settings.cfg")
#app.route('/', defaults={'path': ''}, methods=['GET', 'POST'])
#app.route('/<path:path>', methods=['GET', 'POST'])
def get_resource(path): # pragma: no cover
# If we are devmode, proxy through flask.
if config.getKey("devmode") == True:
url = "http://localhost:%s/%s" % (config.getKey('ng_port'), path)
j = requests.get(url, stream=True, params=request.args)
return make_response(j.text)
# return the results
# return render_template('dist/index.html')
# return app.send_static_file("index.html")
return send_from_directory('dist/', path)
if __name__ == '__main__':
app.run(debug=True, port=int(config.getKey("port"))) # , host='0.0.0.0')
^ A variety of ways here show various attempts to handle this.
I have also looked at and tried projects that use variations of the following:
Flask Cli
Flask-Script
Flask-Bootstrap
None of them have solved this problem when I have tried them.
I have been told that using the hashRoute location strategy in Angular rather than the History PushState strategy will also work, however when I attempted to do that it had the same behavior of losing the page upon refresh (additionally we wish to use server side rendering in the future, and hashRoute location strategy prevents this possibility, among many other downsides).
Possibly related is that Flask seems to reload or re-render the page when it does find the index.html and routes initially, wiping anything printed to the browser dev console. I have seen this in some of the flask examples, but not all, and I'm uncertain what causes this.
When running via ng serve --aot --prod, things work exactly correctly and as expected. It's only when serving via Flask that things break down.
Apologies for the long question and thank you for your time in advance.
I am under the impression this is a normal issue with all SPAs and
that the solution is to always redirect the server to index.html. We
have done this (AFAIK), and attempted multiple ways to do this
You also need to redirect all HTTP errors to index.html.
So I have established a pretty decent understanding of the simple architecture of an angularjs app, calling $http and posting to a php page, and receiving data back.
What I'm wondering, is how to do the same type of function with python. Is it possible to have python act the same, with self contained script files that accept post data and echo json back?
$username = $_POST['username'];
type variable assignment at the beginning of the script, and:
echo json_encode(response);
type response.
I'm wanting to use Python for some Internal Tools for my company, as it offers better libraries for remotely running powershell scripts (as the tools are all linux hosted) and overall just has libraries that fit my needs. I'm just having a difficult time finding a concise answer to how this could be set up.
---EDIT------
So I set up a quick example using the information below.
the angular:
var app = angular.module("api");
app.controller("MainController", ["$scope","$http",MainController]);
function MainController($scope,$http){
$http.post('/api',{test: "hello"})
.then(function(response){
console.log(response.data);
})
}
The flask:
from flask import Flask, request
import json
app = Flask(__name__)
#app.route('/api', methods=['POST', 'GET'])
def api():
if request.method == 'POST':
request.data
return 'You made it' # Just so I originally could see that the flask page
if __name__ == "__main__":
app.run()
I'm getting a 404 for that URL. If I change the angular to look at 'localhost:5000/api' (where my flask app is running),it gives me the error of "Unsupported URL Type".
I am seeing when I do the first case, it tries to look at http://localhost/api , which is correct! except for the port. Which is why I tried to specify the port.
Any suggestions for a next step?
Use flask.
You could host your app on a flask "server" and return the content you'd like too with a python processing.
http://flask.pocoo.org/
Use the documentation to setup a route where you'll POST your data using jquery or whatever, then on the route you can do your python stuff and return a JSON to your angular app if you need to.
from flask import request
#app.route('/test', methods=['POST', 'GET'])
def test():
if request.method == 'POST':
print request.data['your_field']
return your_json_data
Question: What would be a comparable solution to the example at this link, except implemented using gevent-socketio and Socket.io.js with bottle? I'm looking for the minimal solution that will simply pass some traffic in a loop from the client to the server and back to the client using gevent-socketio, Socket.io.js, and bottle.
Background: I have developed a simple web-app that provides a web-based terminal for a remote custom shell (cli) on the server. The browser (client) collects shell commands from a form input field, passes the command over a web-socket to a gevent.pywsgi.WSGIServer handling the requests via the geventwebsocket.WebSocketHandler handler, which supplies the command to the shell, while asynchronously returning output via the socket to a textarea field in a form in the client's browser. This is based on a great, little example provided by the bottle team:
http://bottlepy.org/docs/dev/async.html#finally-websockets
Provided here for redundancy:
example_server.py:
from bottle import request, Bottle, abort
app = Bottle()
#app.route('/websocket')
def handle_websocket():
wsock = request.environ.get('wsgi.websocket')
if not wsock:
abort(400, 'Expected WebSocket request.')
while True:
try:
message = wsock.receive()
wsock.send("Your message was: %r" % message)
except WebSocketError:
break
from gevent.pywsgi import WSGIServer
from geventwebsocket import WebSocketHandler, WebSocketError
server = WSGIServer(("0.0.0.0", 8080), app,
handler_class=WebSocketHandler)
server.serve_forever()
client.html:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
var ws = new WebSocket("ws://example.com:8080/websocket");
ws.onopen = function() {
ws.send("Hello, world");
};
ws.onmessage = function (evt) {
alert(evt.data);
};
</script>
</head>
</html>
Motivation: My existing app works great in the latest version of Firefox and Chrome. IE support is non-existent, and Safari compatibility is middlin'. I'm ultimately looking for a cross-browswer solution to communicate shell commands and output between the client and server. If I had a simple example for bottle, I think I could move forward more quickly.
Incidentally, I looked at the gevent-socketio examples and even a bottle example, but all of these examples are too different from the above simple example for me to make the leap in application. (The gevent-socketio examples look nothing like the bottle apps, which which I'm familiar. And, the bottle example doesn't actually show how to communicate with the client.)
Thanks! :)
Circus! the process runner and watcher built on top of zmq, use bottle and socketio for the web interfaces:
https://github.com/mozilla-services/circus/blob/master/circus/web/circushttpd.py
https://github.com/mozilla-services/circus/blob/master/circus/web/server.py
The source code is simple enough for helping you to get started to build a bigger app with bottle and socketio.
Otherwise, I advice you to move to sockjs! which a more generic implementation with better support for different backends.
This other thread can help you :
SockJS or Socket.IO? Worth to recode ajax-based page?