This question already has answers here:
How to serve static files in Flask
(24 answers)
Closed 6 years ago.
I'm trying to use processing.js on my website but I keep getting the error: "processing.min.js Failed to load resource: the server responded with a status of 404 (NOT FOUND)"
I'm using Flask's render_template() to load in the test.html:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Processing.js</title>
<script src="processing.min.js"></script>
</head>
<body>
<h1>Processing.js</h1>
<script type="text/processing">
void setup() {
size(400,200);
textAlign(CENTER, CENTER);
background(0,0,100);
fill(255,230,75);
text("Processing.js", width/2, height/2);
noLoop();
}
void draw() {
}
void mouseMoved() {
stroke(255);
point(mouseX, mouseY);
redraw();
}
void mousePressed() {
line(0,mouseY,width,mouseY);
line(mouseX,0,mouseX,height);
println(mouseX, mouseY);
}
</script>
<canvas></canvas>
</body>
</html>
The flask file that I then run is simply:
from flask import Flask,request,render_template
app = Flask(__name__)
#app.route("/")
def hello():
return render_template('test.html')
if __name__ == '__main__':
app.debug = True
app.run()
When I run this on the local host: http://127.0.0.1:5000/ I see the header Processing.js but no actual canvas element.
According to Flask docs
Dynamic web applications also need static files. That’s usually where the CSS and JavaScript files are coming from. Ideally your web server is configured to serve them for you, but during development Flask can do that as well. Just create a folder called static in your package or next to your module and it will be available at /static on the application.
And as davidism commented, use the url_for template method to reference files
<script type="text/javascript" src="url_for('static', filename='processing.js')"></script>
Assuming that your static files (.js and .css) are in static folder.
Related
I am creating an interface for a Random Number Generator. Just using the script on my machine, it works perfectly.
But when I host the interface on a Server (IONOS VPS), it does not work properly. I can still access the interface and load the the html. Sometimes it shows one emitted number or 2 and when I still wait sometimes the interface receives another number.
In my python-console I get the periodic GET requests to /socket.io/?EIO=4&transport=polling&t=00maxxx.
This is what my Browser-network-console shows.
enter image description here
I guess that the connection never really happens completely.
I have already checked the compatibility of flask-socketio with my server.
My server code looks like this:
from flask import Flask, render_template
from flask_socketio import SocketIO, emit
from flask_cors import CORS
import eventlet
import threading
eventlet.monkey_patch()
async_mode = None
app = Flask(__name__)
CORS(app)
socketio = SocketIO(app, async_mode='async_mode', logger=True)
# starting background thread
def background_thread():
while True:
socketio.emit('my_response',
{'data': 'Server generated event'})
# create html template
#app.route("/")
def index():
return render_template('index.html', async_mode=socketio.async_mode)
#socketio.event
def my_ping():
emit('my_pong')
<... more vent handlers etc. ...>
if __name__ == '__main__':
PORT = json.load(open('config.json'))["PORT"]
print("Running on localhost:"+str(PORT))
socketio.run(app, debug=True, host='0.0.0.0', port=PORT)
The client looks like this:
<!DOCTYPE HTML>
<html lang="en">
<head>
<!--Used character set -->
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Random Number Generator</title>
<script charset="utf-8" src="{{ url_for('static', filename='js/jquery.min.js') }}">
<script charset="utf-8" src="{{ url_for('static', filename='js/socket.io.js') }}"></script>
<script charset="utf-8" src="{{ url_for('static', filename='js/server.js') }}" type="text/javascript"></script>
</head>
<body>
More HTML here
</body>
</html>
My server.js looks like this
var socket = io();
$(document).ready(function() {
some code
});
// Interval function that tests message latency by sending a "ping"
// message. The server then responds with a "pong" message and the
// round trip time is measured.
var ping_pong_times = [];
var start_time;
window.setInterval(function() {
start_time = (new Date).getTime();
$('#transport').text(socket.io.engine.transport.name);
socket.emit('my_ping');
}, 1000);
// Handler for the "pong" message. When the pong is received, the
// time from the ping is stored, and the average of the last 30
// samples is average and displayed.
socket.on('my_pong', function() {
var latency = (new Date).getTime() - start_time;
ping_pong_times.push(latency);
ping_pong_times = ping_pong_times.slice(-30); // keep last 30 samples
var sum = 0;
for (var i = 0; i < ping_pong_times.length; i++)
sum += ping_pong_times[i];
$('#ping-pong').text(Math.round(10 * sum / ping_pong_times.length) / 10);
});
Anyone has an idea what the problem is?
Your connection probably never upgrades to websockets. If that's the case it stays in polling mode and will poll every 25 seconds. More info on the ping interval
However, I also see you're using eventlet and monkey patching it, but you set your async_mode to the string 'async_mode' instead of the value None you define a bit higher. I would try setting it to 'eventlet', see if that fixes it.
Like this:
import eventlet
import threading
eventlet.monkey_patch()
app = Flask(__name__)
CORS(app)
socketio = SocketIO(app, async_mode='eventlet', logger=True)
Also if you're using the development webserver, you might need to use Gunicorn. Socketio deployment with Gunicorn
I'm having trouble running Flask & SocketIO with Eventlet despite using socketio.run(), any suggestions are appreciated. I'm currently on Python 3.9 and I've tried multiple different versions of each of these modules with no avail.
[2021-04-04 06:39:05,709] WARNING in __init__: Flask-SocketIO is Running under Werkzeug, WebSocket is not available.
"GET /socket.io/?EIO=4&transport=websocket HTTP/1.1" 400 -
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>SAR</title>
<script src="https://cdn.socket.io/3.1.3/socket.io.min.js" integrity="sha384-cPwlPLvBTa3sKAgddT6krw0cJat7egBga3DJepJyrLl4Q9/5WLra3rrnMcyTyOnh" crossorigin="anonymous"></script>
</head>
<body>
<button id="ping" onclick="send()">ping</button>
<script>
var socket = io.connect("http://" + document.domain + ":" + location.port, {transports: ['websocket']});
socket.on("connect", function(){
socket.emit("ping", "Established a connection, pinging!");
});
socket.on("pong", function(response){
console.log(response)
});
function send(){
socket.emit("ping", "ping_data");
}
</script>
</body>
</html>
app.py
from flask import Flask, render_template
from flask_socketio import SocketIO, emit
import eventlet
app = Flask(__name__)
socketio = SocketIO(app, logger=True)
#app.route( '/' )
def index():
return render_template( 'index.html')
def receivedCallback():
print('Pong received by user!')
#socketio.on( 'ping' )
def handle_ping(data):
print("received", data)
socketio.emit('pong', "pong_data", callback=receivedCallback)
if __name__ == '__main__':
socketio.run(app)
It seems like running my main file through the terminal resolves this issue. If anyone knows why this is please do share, thanks. :)
python app.py
To give a loose idea of why it runs with python app.py is that the if __name__ == '__main__' is executed only when it is run through the terminal, much like how the main function is called first in many other programming languages like Java or C when run from the terminal directly.
When a Flask app is run through Werkzeug, the flask app instance is imported and sort of wrapped into a module by Werkzeug in which the requests are routed into. (That is why the if __name__ == __main__ part is never executed – much like when you import another module in your code, the main function of that module is never called.) So, as far as my understanding goes, when you run your Flask app through Werkzeug, the requests are received and routed over HTTP by default and not over the WebSocket protocol that Flask-SocketIO uses when you run socketio.run(). The WebSocket protocol requires a socket to be always open, enabling asynchronous I/O which cannot work in HTTP as it is a client-server protocol.
I, however, do not have an answer to how to solve the problem and work with Flask-SocketIO through Werkzeug, but I hope the above explanation throws some light into your problem and drives you in the correct direction to look at.
I'm creating a Flask app frontend, my index.html can't find the images and files referenced in the code.
I've tried moving to the same folder but with no success.
Server:
from flask import Flask
app = Flask(__name__)
#app.route('/')
def hello():
return open('html/index.html').read()
if __name__ == '__main__':
app.run(host='localhost', port=8000, debug=True)
HTML lines:
<img src="shards-logo-white.svg" alt="Example Navbar 1" class="mr-2" height="30">
<script src="js/shards.min.js"></script>
<script src="js/demo.min.js"></script>
Server debug output:
127.0.0.1 - - [30/Jan/2019 12:19:28] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [30/Jan/2019 12:19:29] "GET /shards-logo-white.svg HTTP/1.1" 404 -
127.0.0.1 - - [30/Jan/2019 12:19:29] "GET /html/js/shards.min.js HTTP/1.1" 404 -
127.0.0.1 - - [30/Jan/2019 12:19:29] "GET /html/js/demo.min.js HTTP/1.1" 404 -
The image shards-logo-white.svg is in the same folder.
The js scripts are with the subdirectory html -> js -> FILES.
No, Flask does not serve arbitrary files from the filesystem. Move any static files like those into the static subdirectory, then reference them via that path; you can use the full path of nested directoriess within the static path:
<img src="/static/shards-logo-white.svg" alt="Example Navbar 1" class="mr-2" height="30">
<script src="/static/html/js/shards.min.js"></script>
<script src="/static/html/js/demo.min.js"></script>
You could serve your HTML rendered from a template, at which point you can use {{ url_for('static', filename="shards-logo-white.svg") }} and {{ url_for('static', filename="html/js/shards.min.js") }}, etc. to have Flask generate valid URLs for those paths.
See the Static Files section of the quickstart, as well as the Static Files chapter of the tutorial.
If you are not using a template then may as well serve your html/index.html file as a static file too. As it stands you are not rendering it as a template nor are you making any other runtime changes to the file contents.
Even if you do sometimes need to conditionally serve a file from disk, rather than read it all into memory I'd use the flask.send_file() function to make sure the file is served efficiently and with a reasonable content-type header:
from flask import send_file
#app.route('/')
def hello():
return send_file('html/index.html')
Relative paths are resolved against Flask.root_path. You probably also want to consider flask.send_from_directory(), which will ensure that user-input for a filename can't be abused to serve arbitrary files outside of a designated directory.
I am doing a very simple thing, just sending a message to my Flask app via Socket.IO . It works like a charm with English, but some other languages break somewhere in the process.
Minimal working example follows.
testapp.py:
from flask import Flask
from flask_socketio import SocketIO
app = Flask('example')
socketio = SocketIO(app)
#socketio.on('test')
def on_connect(data):
print(data)
if __name__ == '__main__':
socketio.run(app)
index.html:
<!doctype html>
<html>
<body>
<script type="text/javascript" src="js/socket.io.js"></script>
<script>
var socket = io.connect('http://localhost:5000');
socket.on('connect', function() {
socket.emit('test', 'ASCII text');
socket.emit('test', 'Český text');
});
</script>
</body>
</html>
Instead of expected Český text, I am getting ÄŚeskĂ˝ text on the console.
I am using the newest versions of both the server packages (Flask-SocketIO 3.0.2, python-socketio 2.0.0, python-engineio 2.2.0) and the client (socket.io.js 2.1.1) and also checked that both of my files are UTF-8 encoded.
Some bug reports and questions mention a breaking change that happenned between 1.x and 2.x versions, so i tried using some older versions of the client (1.4.8, 1.7.4) instead of the newest one. The result was not much better: ÃÅeskÄË text.
This is beginners' stuff, so there must be a popular SO question covering it already. I probably just can't find it. So... what did I miss?
I am new to Python and networking. I am trying some Python code at server side to display some continous data on my client browser. I have taken this sample code from net itself. The problem is that this code works fine on local machine when i try to access it my browser using localhost but doesn't works when i try to access it from other machine. In Ubuntu i doesn't get any data on my browser but in windows i get all data pushed on my browser when i stop the server code. I am using Twisted and Flask in Python for this. Here is the code i am trying:
import random
from twisted.web.server import Site
from twisted.web.wsgi import WSGIResource
from twisted.internet import reactor
import time
from flask import Flask, request, Response
app = Flask(__name__)
def event_stream():
count = 0
while True:
count += 1
yield 'data: %d\n\n' % count
time.sleep(5)
print 'data sent...'
#app.route('/my_event_source')
def sse_request():
return Response(
event_stream(),
mimetype='text/event-stream')
#app.route('/')
def page():
return '''
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="//code.jquery.com/jquery-1.8.0.min.js"></script>
<script type="text/javascript" src="EventSource.js"></script>
<script type="text/javascript">
$(document).ready(
function() {
sse = new EventSource('/my_event_source');
sse.onmessage = function(message) {
console.log('A message has arrived!');
$('#output').append('<li>'+message.data+'</li>');
}
})
</script>
</head>
<body>
<h2>Hello World Example to implement Server Sent Event using Twisted in Python...</h2>
<ul id="output"></ul>
</body>
</html>
'''
if __name__ == '__main__':
print 'starting server...'
resource = WSGIResource(reactor, reactor.getThreadPool(), app)
site = Site(resource)
reactor.listenTCP(9999, site)
reactor.run()
Can someone help me why the data is not getting displayed when i am trying to access it from other machine (or how can i debug it). Any help is greatly appreciated.