If you follow me on Github you have maybe already seen that I currently develop a package manager for Unix, Ubik.
In order to test my API, I create a WebUI for Ubik and the websockets comes to me. My two prefered web framework are Django and Flask, but I need a lightweight web app, so welcome to Flask.
Ok, I have many many times hear good things about Node.js and Socket.io, no doubt. But my focus is to do a lightweight and full Python implemented application.
So, tools are:
By the way, gevent-socketio seems to be a solid socket.io Python implementation.
This is my Flask app structure:
.
├── runserver.py
├── requirements.txt
└── app
├── __init__.py
├── views.py
├── websocket.py
├── static
│ └── ...
└── templates
└── index.html
flask
gevent
gevent-websocket
This is the app core, create your app, import every shared object you want to use into your app, like databases, etc.
And don't forget to import views at the end to avoid circular imports.
# coding: utf-8
import os
from flask import Flask
from websocket import handle_websocket
app = Flask(__name__)
app.secret_key = os.urandom(24)
app.debug = True
def my_app(environ, start_response):
path = environ["PATH_INFO"]
if path == "/":
return app(environ, start_response)
elif path == "/websocket":
handle_websocket(environ["wsgi.websocket"])
else:
return app(environ, start_response)
import views
All your websocket stuff could be here, this is the websocket handler.
Messages from browser arrived here, and you can easily send message throught websocket with send
method from ws
object.
Use json
, please.
# coding: utf-8
import json
def handle_websocket(ws):
while True:
message = ws.receive()
if message is None:
break
else:
message = json.loads(message)
r = "I have received this message from you : %s" % message
r += "<br>Glad to be your webserver."
ws.send(json.dumps({'output': r}))
Simple flask
view to index.html
template.
# coding: utf-8
from flask import render_template
from app import app
@app.route('/')
def index():
return render_template('index.html')
Run your app with this script. It import your app and feed WSGIServer
with it.
#!/usr/bin/env python
# coding: utf-8
from gevent.pywsgi import WSGIServer
from geventwebsocket.handler import WebSocketHandler
from app import my_app
if __name__ == '__main__':
http_server = WSGIServer(('',5000), my_app, handler_class=WebSocketHandler)
http_server.serve_forever()
And a quick Javascript websocket example.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
</head>
<p>Websocket with Flask, Gevent and Gevent-websocket</p>
<p id="log"></p>
<button id="send" type="button">Send!</button>
<body>
<script src="http://code.jquery.com/jquery-1.8.2.min.js"></script>
<script>
$(document).ready(function(){
if ("WebSocket" in window) {
ws = new WebSocket("ws://" + document.domain + ":5000/websocket");
ws.onmessage = function (msg) {
var message = JSON.parse(msg.data);
$("p#log").html(message.output);
};
};
// Bind send button to websocket
$("button#send").live("click", function() {
ws.send(JSON.stringify({'output': 'Sent from my browser!'}));
});
// Cleanly close websocket when unload window
window.onbeforeunload = function() {
ws.onclose = function () {}; // disable onclose handler first
ws.close()
};
});
</script>
</body>
</html>
All can find all this stuff in this repository. Thanks to tzangms.
Play websockets with Flask and Python is fun !
I will continue to improve Ubik webui with websocket and you have to take a look at the 0.2 branch. Bunch of new features is coming !