perspective.handlers.aiohttp
1# ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ 2# ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃ 3# ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃ 4# ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃ 5# ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃ 6# ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫ 7# ┃ Copyright (c) 2017, the Perspective Authors. ┃ 8# ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃ 9# ┃ This file is part of the Perspective library, distributed under the terms ┃ 10# ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃ 11# ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ 12 13from aiohttp import web, WSMsgType 14import perspective 15import asyncio 16 17 18class PerspectiveAIOHTTPHandler(object): 19 """`PerspectiveAIOHTTPHandler` is a drop-in implementation of Perspective. 20 21 Use it inside AIOHTTP routing to create a server-side Perspective that is 22 ready to receive websocket messages from the front-end `perspective-viewer`. 23 24 The Perspective client and server will automatically keep the Websocket 25 alive without timing out. 26 27 # Examples 28 29 >>> server = Server() 30 >>> async def websocket_handler(request): 31 ... handler = PerspectiveAIOHTTPHandler(perspective_server=server, request=request) 32 ... await handler.run() 33 34 >>> app = web.Application() 35 >>> app.router.add_get("/websocket", websocket_handler) 36 """ 37 38 def __init__(self, **kwargs): 39 self.server = kwargs.pop("perspective_server", perspective.GLOBAL_SERVER) 40 self._request = kwargs.pop("request") 41 self._executor = kwargs.pop("executor", None) 42 self._loop = kwargs.pop("loop", asyncio.get_event_loop()) 43 super().__init__(**kwargs) 44 45 async def run(self) -> web.WebSocketResponse: 46 def inner(msg): 47 self._loop.create_task(self._ws.send_bytes(msg)) 48 49 self.session = self.server.new_session(inner) 50 try: 51 self._ws = web.WebSocketResponse() 52 await self._ws.prepare(self._request) 53 async for msg in self._ws: 54 if msg.type == WSMsgType.BINARY: 55 if self._executor is not None: 56 self._executor.submit(self.session.handle_request, msg.data) 57 else: 58 self.session.handle_request(msg.data) 59 finally: 60 self.session.close() 61 return self._ws
class
PerspectiveAIOHTTPHandler:
19class PerspectiveAIOHTTPHandler(object): 20 """`PerspectiveAIOHTTPHandler` is a drop-in implementation of Perspective. 21 22 Use it inside AIOHTTP routing to create a server-side Perspective that is 23 ready to receive websocket messages from the front-end `perspective-viewer`. 24 25 The Perspective client and server will automatically keep the Websocket 26 alive without timing out. 27 28 # Examples 29 30 >>> server = Server() 31 >>> async def websocket_handler(request): 32 ... handler = PerspectiveAIOHTTPHandler(perspective_server=server, request=request) 33 ... await handler.run() 34 35 >>> app = web.Application() 36 >>> app.router.add_get("/websocket", websocket_handler) 37 """ 38 39 def __init__(self, **kwargs): 40 self.server = kwargs.pop("perspective_server", perspective.GLOBAL_SERVER) 41 self._request = kwargs.pop("request") 42 self._executor = kwargs.pop("executor", None) 43 self._loop = kwargs.pop("loop", asyncio.get_event_loop()) 44 super().__init__(**kwargs) 45 46 async def run(self) -> web.WebSocketResponse: 47 def inner(msg): 48 self._loop.create_task(self._ws.send_bytes(msg)) 49 50 self.session = self.server.new_session(inner) 51 try: 52 self._ws = web.WebSocketResponse() 53 await self._ws.prepare(self._request) 54 async for msg in self._ws: 55 if msg.type == WSMsgType.BINARY: 56 if self._executor is not None: 57 self._executor.submit(self.session.handle_request, msg.data) 58 else: 59 self.session.handle_request(msg.data) 60 finally: 61 self.session.close() 62 return self._ws
PerspectiveAIOHTTPHandler
is a drop-in implementation of Perspective.
Use it inside AIOHTTP routing to create a server-side Perspective that is
ready to receive websocket messages from the front-end perspective-viewer
.
The Perspective client and server will automatically keep the Websocket alive without timing out.
Examples
>>> server = Server()
>>> async def websocket_handler(request):
... handler = PerspectiveAIOHTTPHandler(perspective_server=server, request=request)
... await handler.run()
>>> app = web.Application()
>>> app.router.add_get("/websocket", websocket_handler)
async def
run(self) -> aiohttp.web_ws.WebSocketResponse:
46 async def run(self) -> web.WebSocketResponse: 47 def inner(msg): 48 self._loop.create_task(self._ws.send_bytes(msg)) 49 50 self.session = self.server.new_session(inner) 51 try: 52 self._ws = web.WebSocketResponse() 53 await self._ws.prepare(self._request) 54 async for msg in self._ws: 55 if msg.type == WSMsgType.BINARY: 56 if self._executor is not None: 57 self._executor.submit(self.session.handle_request, msg.data) 58 else: 59 self.session.handle_request(msg.data) 60 finally: 61 self.session.close() 62 return self._ws