Source code for araldo.app
#!/usr/bin/env python
""" Handles WebSocket requests and HTTP requests
"""
import logging
import re
from araldo.endpoints.websocket import EndPoint
STATIC_DIR = "."
WEBSOCKET_NAME_RE = re.compile("/websocket/([^/]+)/?")
[docs]class AppException(Exception):
""" An internal exception
"""
def __init__(self, msg):
logging.getLogger("araldo").error(msg)
Exception.__init__(self, msg)
[docs]class WebSocketApp(object):
""" Provides bidirectional communication:
- inbound via WebSocket
- outbound via regular HTTP request
"""
def __init__(self, config, queue, plugin_manager):
self._config = config
self._queue = queue
self._logger = logging.getLogger("araldo")
self._plugin_manager = plugin_manager
plugin_instances = self._plugin_manager.plugin_instances()
outbound = plugin_instances["araldo.endpoints.endpoint"]
self._websockets = outbound
def _handle_websocket(self, environ, web_socket_name):
""" Handle call to websocket.
This method will never return (serves forever)
:param environ: environment passed by WSGIServer
"""
#self._logger.debug("Received WebSocket call: %s" % environ)
web_socket = environ["wsgi.websocket"]
self._logger.debug("Adding websocket '%s'" % web_socket_name)
#self._logger.debug("### %s" % web_socket.__class__)
web_socket_conf = self._plugin_manager.plugin_subconfig(
"araldo.endpoints.endpoint", web_socket_name)
endpoint = EndPoint(
config=web_socket_conf,
gevent_queue=self._queue,
name=web_socket_name,
plugin_manager=self._plugin_manager,
web_socket=web_socket)
self._websockets[web_socket_name] = endpoint
endpoint._run()
@staticmethod
def _parse_websocket_name(path_info):
""" Extract web socket name from URL path
"""
match = WEBSOCKET_NAME_RE.match(path_info)
if not match:
raise AppException("Unable to determine WebSocket name")
return match.group(1)
[docs] def __call__(self, environ, start_response):
""" main WSGI method
"""
path_info = environ["PATH_INFO"]
if path_info.startswith('/websocket'):
self._handle_websocket(
environ,
WebSocketApp._parse_websocket_name(path_info))
#elif path_info == '/outbound':
# return self._handle_outbound(environ, start_response)
else:
start_response('404 NOT FOUND', [('Content-Type', 'text/html')])
return ["<h1>Not found</h1"]
self._logger.debug("returning")