How do I get this websocket example to work with Flask? - javascript

I'm trying to use Kenneth reitz's Flask-Sockets library to write a simple websocket interface/server. Here is what I have so far.
from flask import Flask
from flask_sockets import Sockets
app = Flask(__name__)
sockets = Sockets(app)
#sockets.route('/echo')
def echo_socket(ws):
while True:
message = ws.receive()
ws.send(message)
#app.route('/')
def hello():
return \
'''
<html>
<head>
<title>Admin</title>
<script type="text/javascript">
var ws = new WebSocket("ws://" + location.host + "/echo");
ws.onmessage = function(evt){
var received_msg = evt.data;
alert(received_msg);
};
ws.onopen = function(){
ws.send("hello john");
};
</script>
</head>
<body>
<p>hello world</p>
</body>
</html>
'''
if __name__ == "__main__":
app.run(debug=True)
What I am expecting to happen is when I go to the default flask page, http://localhost:5000 in my case, I will see an alert box with the text hello john, however instead I get a Firefox error. The error is Firefox can't establish a connection to the server at ws://localhost:5000/echo. How do I make hello john show up in the alert box by sending a message to the web server then echoing the reply?

Using gevent-websocket (See gevent-websocket usage):
if __name__ == "__main__":
from gevent import pywsgi
from geventwebsocket.handler import WebSocketHandler
server = pywsgi.WSGIServer(('', 5000), app, handler_class=WebSocketHandler)
server.serve_forever()
Or run the server using gunicorn (See Flask-Sockets Deployment):
gunicorn -k flask_sockets.worker module_name:app

Related

Run python script with flask from web without clicking any button

In my application, I need to open web cam inside webpage and also I need to process web cam frame and return result to webpage again. To do that I am not using buttons. I found that how to use webcam in webpage in here
web cam in a webpage using flask and python
However I cannot pass the result to the webpage. How can I pass the result to the same webpage ? Without clicking any button. In my case how can I call, index2() function from web ?
Python
from flask import Flask, render_template, Response, jsonify
from camera import VideoCamera
import cv2
app = Flask(__name__)
video_stream = VideoCamera()
#app.route('/')
def index():
return render_template('index.html')
def gen(camera):
while True:
frame = camera.get_frame()
yield (b'--frame\r\n'
b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n')
#app.route('/video_feed')
def video_feed():
return Response(gen(video_stream),
mimetype='multipart/x-mixed-replace; boundary=frame')
#app.route('/print2')
def index2():
print2 = video_stream.get_print()
print("zzzz",print2)
return render_template('gui.html', printTo=print2)
if __name__ == '__main__':
app.run(host='127.0.0.1', debug=True,port="5000")
Python camera.py
class VideoCamera(object):
def __init__(self):
self.video = cv2.VideoCapture(0)
def __del__(self):
self.video.release()
def get_frame(self):
ret, frame = self.video.read()
# DO WHAT YOU WANT WITH TENSORFLOW / KERAS AND OPENCV
ret, jpeg = cv2.imencode('.jpg', frame)
return jpeg.tobytes()
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<title>Video Stream</title>
</head>
<body>
<img src="{{ url_for('video_feed') }}" />
</body>
</html>
In camera.py script I can process frame and I can print the results to log however I need to pass these results to the webpage.
I did many thing and none of them worked for me !
Please help me.
Thank you.
EDIT
As the comments states, as far as I understand I can do it with AJAX and I added this script but now script gives error
<script type="text/javascript" >
function plot() {
$.ajax({
url: '/print2',
success: function(data) {
console.log('get info');
$('#description').html(data['description']);
}
});
}
plot()
</script>
It says
(index):30 Uncaught ReferenceError: $ is not defined
at plot ((index):30)
at (index):38
Where is the problem ?
Have you included a reference to jQuery?
(index):30 Uncaught ReferenceError: $ is not defined at plot ((index):30) at (index):38

XMLHTTPRequest between Python and Javascript

Here is a function in javascript which is currently being used to update a database. Currently when it is run, the entire python script is outputted to the javascript function intead of just the print statement. Is it possible, without importing any extra modules, for data to be sent between these two sections of code? if so, how would I do it?
Javascript:
function sendmsg(){
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
// Typical action to be performed when the document is ready:
console.log(xhttp.responseText)
document.getElementById("name").innerHTML = '';
}
};
xhttp.open("GET", URL+'/SendMsg.py', true);
xhttp.send();
}
Python:
import cgi
import cgitb; cgitb.enable()
import sqlite3
mydb = 'messenger.db'
conn = sqlite3.connect(mydb)
cursor = conn.cursor()
print('alex')
"""
form = cgi.FieldStorage()
Sender = form.getvalue('UserName')
Reciever = form.getvalue('Class')
message = form.getvalue('Message')
val = {"Sender":Sender, "Reciever":Reciever, "message":message}
cursor.execute('''INSERT INTO Message (Message, SenderID, ClassID) VALUES (:message, :Sender, :Reciever)''',val)
conn.commit()
cursor.close()
"""
Many thanks in advance
Ive fixed this problem, There was a error in the config file of apache which didnt allow python cgi to run how it is created to run. For future, make sure that the required lines of code in the config files are uncommented.
I would suggest to take a look at Flask or Django. You can implement a RESTful API using Django or Flask, read the HTTP request there, extract parameter and send back appropriate response.
Right now you are requesting the server to send xhttp.open("GET", URL+'/SendMsg.py', true); SendMsg.py and it's sending that.

Removing image accessibility

I have a web page that is feed from flask a link to a picture. I have it so the image disappears after a second or two. However, if you look at the page source you can still get the picture, via finding the exact url for the picture. How do I remove access to the url or remove the picture from the url so that the user can no longer view the image after it disappears.
Html Page:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Welcome</title>
<script src="//code.jquery.com/jquery-1.11.0.min.js"></script>
</head>
<body>
<script type="text/javascript">
$(document).ready(function () {
var c = document.getElementById('image');
console.log(typeof(c));
setTimeout(function () {
$('#des').css('visibility', 'hidden');
}, 1750);
fs.unlink("{{ url_for('static', filename = '1l1l1lI1lIlIlIlI1IlI1II1l1.jpg') }}");
removeElement(c)
storage.clear(c);
sessionStorage.clear(c);
});
</script>
<div id="des">
<img id="image" src="{{ url_for('static', filename = '1l1l1lI1lIlIlIlI1IlI1II1l1.jpg') }}"/>
</div>
</body>
</html>
main.py
from datetime import datetime
from flask import make_response
from functools import wraps, update_wrapper
from flask import Flask, request, session, g, redirect, url_for, abort, \
render_template, flash
app = Flask(__name__) # create the application instance
app.config.from_object(__name__) # load config from this file , flaskr.py
def nocache(view):
#wraps(view)
def no_cache(*args, **kwargs):
response = make_response(view(*args, **kwargs))
response.headers['Last-Modified'] = datetime.now()
response.headers['Cache-Control'] = 'no-store, no-cache, must-revalidate, post-check=0, pre-check=0, max-age=0'
response.headers['Pragma'] = 'no-cache'
response.headers['Expires'] = '-1'
return response
return update_wrapper(no_cache, view)
#app.route(r'/')
#nocache
def landingpage():
return render_template('index.html')
if __name__ == '__main__':
app.run()
First and foremost your images won't be protected if the user tries hard enough. You cannot prevent them for taking screen shots or anything of the sort.
There are several ways to help "prevent" them from getting your images:
You can load your image via ajax:
<script>
$('#my_image').attr('src', {{ url_for('image_path') }});
</script>
You can also load via an expiring hash key (database driven). So create a table with a mapping to the file name and then load the image using a route by passing in the hash key. If they try to open the image from a debugger, it can say it was expired and won't load the image.
def get_image(self, hash_key):
my_image = self.image_engine.get_image(hash_key)
if my_image.get('is_viewed') == 0:
real_key = my_image.get('real_key')
root_path = os.path.join(self.image_path, real_key)
# call a function to set the image as "viewed"
return send_from_directory(root_path, '{}.png'.format(real_key))
else:
return render_template('404.html')
Doing it like this means you can add expiration to the hash key, or even a flag that says it was already viewed and then render nothing, or a 404 if they try to load it again.
This method does require a lot more database calls, but if you are out to protect your images, you will have to look at some performance options.

Display the contents of a text file within iframe in a html page rendered via flask web server

This is probably a simple question but I got somehow confused.
I'm using flask webserver to keep my UI up. This server generates a log file. I want to have, let's say, an iframe below the html page (the one which is rendered via flask render_template('index.html') ) showing the contents of that file.
I'm aware of the questions like this and thanks to #davidism I've learnt nice concepts about serving the static files but that's not exactly what I want to achieve.
So far I can say, again thanks to #davidism, that I have a main.py file like this:
from time import sleep
from flask import Flask, render_template
app = Flask(__name__)
#app.route('/')
def index():
return render_template('index.html')
#app.route('/stream')
def stream():
def generate():
with open('job.log') as f:
while True:
yield f.read()
sleep(1)
return app.response_class(generate(), mimetype='text/plain')
app.run()
and by using this:
<pre id="output"></pre>
<script>
var output = document.getElementById('output');
var xhr = new XMLHttpRequest();
xhr.open('GET', '{{ url_for('stream') }}');
xhr.send();
setInterval(function() {
output.textContent = xhr.responseText;
}, 1000);
</script>
I get that log in a clean full page. How can I get this in that aforementioned way.
p.s: I have multiple html files which will be rendered in the future and I want to implement this in a way to have that iframe view of the log file in all pages.
An iframe is literally just another page contained within an element on your page. So your main page would just do:
<iframe src ="/stream"></iframe>
and that's it.

PySide. Extracting DOM HTML. AccessNetworkmanager

I need to extract all calendar data from page like
"http://www.dukascopy.com/swiss/english/marketwatch/calendars/eccalendar/". Firstly - to extract all html with inner dom.
Using eclipse and Python 3.3, win7. Searched here answers, and coded smth based on them.
Looks like:
from PySide import QtGui, QtDeclarative
from PySide.QtGui import QApplication, QDesktopServices, QImage, QPainter
from PySide.QtCore import QByteArray, QUrl, QTimer, QEventLoop, QIODevice, QObject
from PySide.QtWebKit import QWebFrame, QWebView, QWebPage, QWebSettings
from PySide.QtNetwork import QNetworkAccessManager, QNetworkProxy, QNetworkRequest, QNetworkReply, QNetworkDiskCache
#!/usr/bin/env python
"""
app = QApplication(sys.argv)
web = QWebView()
web.load(QUrl("http://www.dukascopy.com/swiss/english/marketwatch/calendars/eccalendar/"))
web.show()
sys.exit(app.exec_())
"""
app = QApplication(sys.argv)
w = QWebView()
request = QNetworkRequest(QUrl("http://www.dukascopy.com/swiss/english/marketwatch/calendars/eccalendar/"))
reply = w.page().networkAccessManager().get(request)
print(reply)
byte_array = reply.readAll()
plist = reply.rawHeaderList()
print(plist)
print(byte_array)
When loading page to QWebView() it works fine (commented code), but I couldn't find how to extract all html from QWebView(). So i tried via "request" - decommented code. And nothing prints.
Try with signals:
def print_content():
print web.page().mainFrame().toHtml() # or toPlainText()
# or
# print web.page().currentFrame().toHtml() # or toPlainText()
and
web.page().mainFrame().loadFinished.connect(print_content)
# or web.loadFinished.connect(print_content)
web.load(QUrl("http://www.dukascopy.com/swiss/english/marketwatch/calendars/eccalendar/"))
web.show()
print_content should be called then loadFinished signal arrives

Categories