Source code for csbot.plugins.webserver

"""
Creates a web server using :mod:`aiohttp` so that other plugins can register URL handlers.

To register a URL handler, a plugin should hook the ``webserver.build`` event and create a sub-application,
for example::

    class MyPlugin(Plugin):
        @Plugin.hook('webserver.build')
        def create_app(self, e):
            with e['webserver'].create_subapp('/my_plugin') as app:
                app.add_routes([web.get('/{item}', self.request_handler)])

        async def request_handler(self, request):
            return web.Response(text=f'No {request.match_info["item"]} here, oh dear!')

Configuration
=============

The following configuration options are supported in the ``[webserver]`` config section:

==================  ===========
Setting             Description
==================  ===========
``host``            Hostname/IP address to listen on. Default: ``localhost``.
``port``            Port to listen on. Default: ``1337``.
==================  ===========

Module contents
===============
"""


from contextlib import contextmanager

from aiohttp import web

from ..plugin import Plugin


[docs]class WebServer(Plugin): CONFIG_DEFAULTS = { 'host': 'localhost', 'port': 1337, }
[docs] def setup(self): # Setup server self.bot.loop.run_until_complete(self._build_app()) self.bot.loop.run_until_complete(self._start_app())
async def _build_app(self): self.app = web.Application() await self.bot.emit_new('webserver.build', { 'webserver': self, }) async def _start_app(self): self.app_runner = web.AppRunner(self.app) await self.app_runner.setup() self.site = web.TCPSite(self.app_runner, self.config_get('host'), self.config_get('port')) await self.site.start() async def _stop_app(self): await self.app_runner.cleanup() self.app_runner = None self.site = None
[docs] def teardown(self): self.bot.loop.run_until_complete(self._stop_app()) super().teardown()
[docs] @contextmanager def create_subapp(self, prefix): self.log.info(f'Registering web application at {prefix}') app = web.Application() yield app self.app.add_subapp(prefix, app)