Flask-Sockets-0.2.1/0000755000076500000240000000000012724705347016033 5ustar kennethreitzstaff00000000000000Flask-Sockets-0.2.1/Flask_Sockets.egg-info/0000755000076500000240000000000012724705347022260 5ustar kennethreitzstaff00000000000000Flask-Sockets-0.2.1/Flask_Sockets.egg-info/dependency_links.txt0000644000076500000240000000000112724705347026326 0ustar kennethreitzstaff00000000000000 Flask-Sockets-0.2.1/Flask_Sockets.egg-info/not-zip-safe0000644000076500000240000000000112654542105024477 0ustar kennethreitzstaff00000000000000 Flask-Sockets-0.2.1/Flask_Sockets.egg-info/PKG-INFO0000644000076500000240000000134312724705347023356 0ustar kennethreitzstaff00000000000000Metadata-Version: 1.1 Name: Flask-Sockets Version: 0.2.1 Summary: Elegant WebSockets for your Flask apps. Home-page: https://github.com/kennethreitz/flask-sockets Author: Kenneth Reitz Author-email: _@kennethreitz.com License: See License Description: Flask-Sockets ------------- Elegant WebSockets for your Flask apps. Platform: any Classifier: Environment :: Web Environment Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: BSD License Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content Classifier: Topic :: Software Development :: Libraries :: Python Modules Flask-Sockets-0.2.1/Flask_Sockets.egg-info/requires.txt0000644000076500000240000000003612724705347024657 0ustar kennethreitzstaff00000000000000Flask gevent gevent-websocket Flask-Sockets-0.2.1/Flask_Sockets.egg-info/SOURCES.txt0000644000076500000240000000040012724705347024136 0ustar kennethreitzstaff00000000000000README.rst flask_sockets.py setup.py Flask_Sockets.egg-info/PKG-INFO Flask_Sockets.egg-info/SOURCES.txt Flask_Sockets.egg-info/dependency_links.txt Flask_Sockets.egg-info/not-zip-safe Flask_Sockets.egg-info/requires.txt Flask_Sockets.egg-info/top_level.txtFlask-Sockets-0.2.1/Flask_Sockets.egg-info/top_level.txt0000644000076500000240000000001612724705347025007 0ustar kennethreitzstaff00000000000000flask_sockets Flask-Sockets-0.2.1/flask_sockets.py0000644000076500000240000000660012724705326021237 0ustar kennethreitzstaff00000000000000# -*- coding: utf-8 -*- from werkzeug.routing import Map, Rule from werkzeug.exceptions import NotFound def log_request(self): log = self.server.log if log: if hasattr(log, 'info'): log.info(self.format_request() + '\n') else: log.write(self.format_request() + '\n') # Monkeys are made for freedom. try: import gevent from geventwebsocket.gunicorn.workers import GeventWebSocketWorker as Worker except ImportError: pass if 'gevent' in locals(): # Freedom-Patch logger for Gunicorn. if hasattr(gevent, 'pywsgi'): gevent.pywsgi.WSGIHandler.log_request = log_request class SocketMiddleware(object): def __init__(self, wsgi_app, app, socket): self.ws = socket self.app = app self.wsgi_app = wsgi_app def __call__(self, environ, start_response): adapter = self.ws.url_map.bind_to_environ(environ) try: handler, values = adapter.match() environment = environ['wsgi.websocket'] with self.app.app_context(): with self.app.request_context(environ): handler(environment, **values) return [] except (NotFound, KeyError): return self.wsgi_app(environ, start_response) class Sockets(object): def __init__(self, app=None): #: Compatibility with 'Flask' application. #: The :class:`~werkzeug.routing.Map` for this instance. You can use #: this to change the routing converters after the class was created #: but before any routes are connected. self.url_map = Map() #: Compatibility with 'Flask' application. #: All the attached blueprints in a dictionary by name. Blueprints #: can be attached multiple times so this dictionary does not tell #: you how often they got attached. self.blueprints = {} self._blueprint_order = [] if app: self.init_app(app) def init_app(self, app): app.wsgi_app = SocketMiddleware(app.wsgi_app, app, self) def route(self, rule, **options): def decorator(f): endpoint = options.pop('endpoint', None) self.add_url_rule(rule, endpoint, f, **options) return f return decorator def add_url_rule(self, rule, _, f, **options): self.url_map.add(Rule(rule, endpoint=f)) def register_blueprint(self, blueprint, **options): """ Registers a blueprint for web sockets like for 'Flask' application. Decorator :meth:`~flask.app.setupmethod` is not applied, because it requires ``debug`` and ``_got_first_request`` attributes to be defined. """ first_registration = False if blueprint.name in self.blueprints: assert self.blueprints[blueprint.name] is blueprint, ( 'A blueprint\'s name collision occurred between %r and ' '%r. Both share the same name "%s". Blueprints that ' 'are created on the fly need unique names.' % (blueprint, self.blueprints[blueprint.name], blueprint.name)) else: self.blueprints[blueprint.name] = blueprint self._blueprint_order.append(blueprint) first_registration = True blueprint.register(self, options, first_registration) # CLI sugar. if 'Worker' in locals(): worker = Worker Flask-Sockets-0.2.1/PKG-INFO0000644000076500000240000000134312724705347017131 0ustar kennethreitzstaff00000000000000Metadata-Version: 1.1 Name: Flask-Sockets Version: 0.2.1 Summary: Elegant WebSockets for your Flask apps. Home-page: https://github.com/kennethreitz/flask-sockets Author: Kenneth Reitz Author-email: _@kennethreitz.com License: See License Description: Flask-Sockets ------------- Elegant WebSockets for your Flask apps. Platform: any Classifier: Environment :: Web Environment Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: BSD License Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content Classifier: Topic :: Software Development :: Libraries :: Python Modules Flask-Sockets-0.2.1/README.rst0000644000076500000240000000655512724705326017532 0ustar kennethreitzstaff00000000000000Flask-Sockets ============= Elegant WebSockets for your Flask apps. .. image:: http://farm4.staticflickr.com/3689/9755961864_577e32a106_c.jpg Simple usage of ``route`` decorator: .. code-block:: python from flask import Flask from flask_sockets import Sockets app = Flask(__name__) sockets = Sockets(app) @sockets.route('/echo') def echo_socket(ws): while not ws.closed: message = ws.receive() ws.send(message) @app.route('/') def hello(): return 'Hello World!' if __name__ == "__main__": from gevent import pywsgi from geventwebsocket.handler import WebSocketHandler server = pywsgi.WSGIServer(('', 5000), app, handler_class=WebSocketHandler) server.serve_forever() Usage of `Flask blueprints`_: .. code-block:: python from flask import Flask, Blueprint from flask_sockets import Sockets html = Blueprint(r'html', __name__) ws = Blueprint(r'ws', __name__) @html.route('/') def hello(): return 'Hello World!' @ws.route('/echo') def echo_socket(socket): while not socket.closed: message = socket.receive() socket.send(message) app = Flask(__name__) sockets = Sockets(app) app.register_blueprint(html, url_prefix=r'/') sockets.register_blueprint(ws, url_prefix=r'/') if __name__ == "__main__": from gevent import pywsgi from geventwebsocket.handler import WebSocketHandler server = pywsgi.WSGIServer(('', 5000), app, handler_class=WebSocketHandler) server.serve_forever() Serving WebSockets in Python was really difficult. Now it's not. Installation ------------ To install Flask-Sockets, simply:: $ pip install Flask-Sockets Deployment ---------- A custom Gunicorn worker is included to make deployment as friendly as possible:: $ gunicorn -k flask_sockets.worker hello:app Production services are provided by `gevent `_ and `gevent-websocket `_. The given example can run standalone as main. Anything that inserts ``wsgi.websocket`` into the WSGI environ is supported, but gevent-websocket is recommended. Development / Testing --------------------- Because the Werkzeug development server cannot provide the WSGI environ with a websocket interface, it is not possible to run a Flask app using the standard ``app.run()``. If you try to, Flask will still try to serve on all the specified routes, and throw a ``KeyError`` whenever a client tries to connect to a websocket route. Instead, just use the included gunicorn worker (explained above), or anything that can insert ``wsgi.websocket`` into the WSGI environ. WebSocket Interface ------------------- The websocket interface that is passed into your routes is `provided by gevent-websocket `_. The basic methods are fairly straightforward —  ``send``, ``receive``, ``send_frame``, and ``close``. Release History --------------- v0.2.1 ~~~~~~ - Add support of `Flask blueprints`_. v0.2.0 ~~~~~~ - Add request context into the socket handler. - Fallback to Flask logic if websocket environment is not available. - Use Flask routing to allow for variables in URL v0.1.0 ~~~~~~ - Initial release. .. _Flask blueprints: http://flask.pocoo.org/docs/latest/blueprints/ Flask-Sockets-0.2.1/setup.cfg0000644000076500000240000000007312724705347017654 0ustar kennethreitzstaff00000000000000[egg_info] tag_build = tag_date = 0 tag_svn_revision = 0 Flask-Sockets-0.2.1/setup.py0000644000076500000240000000175312724705326017550 0ustar kennethreitzstaff00000000000000#!/usr/bin/env python """ Flask-Sockets ------------- Elegant WebSockets for your Flask apps. """ from setuptools import setup setup( name='Flask-Sockets', version='0.2.1', url='https://github.com/kennethreitz/flask-sockets', license='See License', author='Kenneth Reitz', author_email='_@kennethreitz.com', description='Elegant WebSockets for your Flask apps.', long_description=__doc__, py_modules=['flask_sockets'], zip_safe=False, include_package_data=True, platforms='any', install_requires=[ 'Flask', 'gevent', 'gevent-websocket' ], classifiers=[ 'Environment :: Web Environment', 'Intended Audience :: Developers', 'License :: OSI Approved :: BSD License', 'Operating System :: OS Independent', 'Programming Language :: Python', 'Topic :: Internet :: WWW/HTTP :: Dynamic Content', 'Topic :: Software Development :: Libraries :: Python Modules' ] )