flask url confusion – getting 404 or 500 dependng on url
Question:
I am new to web programming.
Writing a simple ajax call to run a python function via 2 files
javascriptPython3.html & javascriptPython3.py
Client is a macbook & firefox 80.0.1
Webserver is a raspberry pi Apache/2.4.25 (Raspbian) Server at rbp Port 80
On the server I run:
export FLASK_DEBUG=1
export FLASK_APP=javascriptPython3.py
flask run -h 192.168.1.6
* Serving Flask app "javascriptPython3"
* Forcing debug mode on
* Running on http://192.168.1.6:5000/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger pin code: 318-477-733
192.168.1.3 - - [10/Dec/2022 14:44:55] "GET / HTTP/1.1" 200 -
192.168.1.3 - - [10/Dec/2022 14:44:57] "GET / HTTP/1.1" 200 -
192.168.1.3 - - [10/Dec/2022 14:44:58] "GET / HTTP/1.1" 200 -
On the client macbook browser:
http://192.168.1.6:5000/
Each Time I reload the webpage, I get an output line in the flask run.
So far so good.
But when I browse to javascriptPython3.html on the client, and click the button, I get 404 not found in the browser console.
If I change the ajax url to "javascriptPython3.py" I get 500 Internal Server error.
#!/usr/bin/env python3
#from flask import Flask, request, render_template
from flask import Flask
app = Flask(__name__)
@app.route('/', methods=['GET','POST'])
def makeupper():
# javascriptdata=request
# javascriptdata=javascriptdata.upper()
outputfile = open("javascriptPython.out", "a")
outputfile.write("Hello from Pythonnn")
return "ABCCC"
javascriptPython3.html:
<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>
function successFun(pythonResponse) {
window.alert(pythonResponse);
document.getElementById('output1').value = pythonResponse;
}
function runPython() {
window.alert("We just called runPython()");
$.ajax({
type: "POST",
url: "/javascriptPython3.py",
// url: "/",
// data: "abc",
success: successFun()
});
}
</script>
</head>
<body>
<p> run python from javascrpt </p>
<br>
<input type="button" onClick="runPython()" value="Run Python" />
<br>
<br>
<p> Output text </p>
<textarea id="output1" rows="4" cols="50"> </textarea>
</body>
</html>
I was expecting to see javascriptPython.out get appended everytime
I clicked the button.
It got appended when I kept reloading http://192.168.1.6:5000/ just as I wanted it to
Answers:
But when I browse to javascriptPython3.html on the client
That is correct. In your code, there is no route for javascriptPython3.html
A very high level/simplistic explanation
-
Flask returns (serves up) content based on paths (routes) you have defined in your python code. It can return content as plain text or it can return the content via a template (html page) i.e. render_template(<html_page>)
-
In your code, you have only defined one route – @app.route('/'
which corresponds to http://192.168.1.6:5000/ . Think of it this way – anything you have defined in as a route comes after your server address which is http://192.168.1.6:5000
-
If you want to navigate to javascriptPython3.html
i.e. you want to be able to type the url http://192.168.1.6:5000/javascriptPython3.html, then you have to define a route for it in your code i.e. you need something like app.route('/javascriptPython3.html')
-
Since it looks like you want to display javascriptPython3.html
when you open your server (i.e when you go to your root i.e. /
), you should modify your existing code to
from flask import Flask, request, render_template
app = Flask(__name__)
@app.route('/', methods=['GET','POST'])
def makeupper():
outputfile = open("javascriptPython.out", "a")
outputfile.write("Hello from Pythonnn")
return render_template('javascriptPython3.html')
I finally got it working ; Again I was trying to simply route to (run) a python function via ajax call.
I just needed to use a complete URL with IP and port, pointing to the apache server in my html file
AJAX URL: url: "http://192.168.1.9:5000/foo",
python route: @app.route('/foo', methods=['GET','POST'])
Below are the 2 files that work
export FLASK_APP=javascriptPython3.py
export FLASK_DEBUG=1
flask run -h 192.168.1.9
Browse to: http://192.168.1.9/javascriptPython3.html
#!/usr/bin/env python3
from flask import Flask, request, render_template
app = Flask(__name__)
@app.route('/foo', methods=['GET','POST'])
def foo():
# javascriptdata=request
# javascriptdata=javascriptdata.upper()
outputfile = open("javascriptPython.out", "a")
outputfile.write("Hello from Pythonnn")
return "ABCCC"
<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.
min.js"></script>
<script>
function successFun(pythonResponse) {
window.alert(pythonResponse);
document.getElementById('output1').value = pythonResponse;
}
function runPython() {
window.alert("We just called runPython()");
$.ajax({
type: "GET",
url: "http://192.168.1.9:5000/foo",
// data: "abc",
success: successFun()
})
}
</script>
</head>
<body>
<p> run python from javascrpt </p>
<br>
<input type="button" onClick="runPython()" value="Run Python" />
<br>
<br>
<p> Output text </p>
<textarea id="output1" rows="4" cols="50"> </textarea>
</body>
</html>
I am new to web programming.
Writing a simple ajax call to run a python function via 2 files
javascriptPython3.html & javascriptPython3.py
Client is a macbook & firefox 80.0.1
Webserver is a raspberry pi Apache/2.4.25 (Raspbian) Server at rbp Port 80
On the server I run:
export FLASK_DEBUG=1
export FLASK_APP=javascriptPython3.py
flask run -h 192.168.1.6
* Serving Flask app "javascriptPython3"
* Forcing debug mode on
* Running on http://192.168.1.6:5000/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger pin code: 318-477-733
192.168.1.3 - - [10/Dec/2022 14:44:55] "GET / HTTP/1.1" 200 -
192.168.1.3 - - [10/Dec/2022 14:44:57] "GET / HTTP/1.1" 200 -
192.168.1.3 - - [10/Dec/2022 14:44:58] "GET / HTTP/1.1" 200 -
On the client macbook browser:
http://192.168.1.6:5000/
Each Time I reload the webpage, I get an output line in the flask run.
So far so good.
But when I browse to javascriptPython3.html on the client, and click the button, I get 404 not found in the browser console.
If I change the ajax url to "javascriptPython3.py" I get 500 Internal Server error.
#!/usr/bin/env python3
#from flask import Flask, request, render_template
from flask import Flask
app = Flask(__name__)
@app.route('/', methods=['GET','POST'])
def makeupper():
# javascriptdata=request
# javascriptdata=javascriptdata.upper()
outputfile = open("javascriptPython.out", "a")
outputfile.write("Hello from Pythonnn")
return "ABCCC"
javascriptPython3.html:
<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>
function successFun(pythonResponse) {
window.alert(pythonResponse);
document.getElementById('output1').value = pythonResponse;
}
function runPython() {
window.alert("We just called runPython()");
$.ajax({
type: "POST",
url: "/javascriptPython3.py",
// url: "/",
// data: "abc",
success: successFun()
});
}
</script>
</head>
<body>
<p> run python from javascrpt </p>
<br>
<input type="button" onClick="runPython()" value="Run Python" />
<br>
<br>
<p> Output text </p>
<textarea id="output1" rows="4" cols="50"> </textarea>
</body>
</html>
I was expecting to see javascriptPython.out get appended everytime
I clicked the button.
It got appended when I kept reloading http://192.168.1.6:5000/ just as I wanted it to
But when I browse to javascriptPython3.html on the client
That is correct. In your code, there is no route for javascriptPython3.html
A very high level/simplistic explanation
-
Flask returns (serves up) content based on paths (routes) you have defined in your python code. It can return content as plain text or it can return the content via a template (html page) i.e.
render_template(<html_page>)
-
In your code, you have only defined one route –
@app.route('/'
which corresponds to http://192.168.1.6:5000/ . Think of it this way – anything you have defined in as a route comes after your server address which is http://192.168.1.6:5000 -
If you want to navigate to
javascriptPython3.html
i.e. you want to be able to type the url http://192.168.1.6:5000/javascriptPython3.html, then you have to define a route for it in your code i.e. you need something likeapp.route('/javascriptPython3.html')
-
Since it looks like you want to display
javascriptPython3.html
when you open your server (i.e when you go to your root i.e./
), you should modify your existing code to
from flask import Flask, request, render_template
app = Flask(__name__)
@app.route('/', methods=['GET','POST'])
def makeupper():
outputfile = open("javascriptPython.out", "a")
outputfile.write("Hello from Pythonnn")
return render_template('javascriptPython3.html')
I finally got it working ; Again I was trying to simply route to (run) a python function via ajax call.
I just needed to use a complete URL with IP and port, pointing to the apache server in my html file
AJAX URL: url: "http://192.168.1.9:5000/foo",
python route: @app.route('/foo', methods=['GET','POST'])
Below are the 2 files that work
export FLASK_APP=javascriptPython3.py
export FLASK_DEBUG=1
flask run -h 192.168.1.9
Browse to: http://192.168.1.9/javascriptPython3.html
#!/usr/bin/env python3
from flask import Flask, request, render_template
app = Flask(__name__)
@app.route('/foo', methods=['GET','POST'])
def foo():
# javascriptdata=request
# javascriptdata=javascriptdata.upper()
outputfile = open("javascriptPython.out", "a")
outputfile.write("Hello from Pythonnn")
return "ABCCC"
<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.
min.js"></script>
<script>
function successFun(pythonResponse) {
window.alert(pythonResponse);
document.getElementById('output1').value = pythonResponse;
}
function runPython() {
window.alert("We just called runPython()");
$.ajax({
type: "GET",
url: "http://192.168.1.9:5000/foo",
// data: "abc",
success: successFun()
})
}
</script>
</head>
<body>
<p> run python from javascrpt </p>
<br>
<input type="button" onClick="runPython()" value="Run Python" />
<br>
<br>
<p> Output text </p>
<textarea id="output1" rows="4" cols="50"> </textarea>
</body>
</html>