ctp-slack-bot / src /ctp_slack_bot /services /http_server_service.py
LiKenun's picture
Refactor #5
a1a6d79
from aiohttp.web import Application, AppRunner, Response, RouteTableDef, TCPSite
from dependency_injector.containers import DeclarativeContainer
from dependency_injector.resources import AsyncResource
from itertools import chain
from loguru import logger
from pydantic import ConfigDict, PrivateAttr
from typing import Self, Sequence
from ctp_slack_bot.controllers.base import ControllerBase, Route
from ctp_slack_bot.core import ApplicationComponentBase, Settings
class HTTPServer(ApplicationComponentBase):
model_config = ConfigDict(frozen=True)
settings: Settings
routes: Sequence[Route]
_app_runner: AppRunner = PrivateAttr()
_site: TCPSite = PrivateAttr()
async def initialize(self: Self) -> None:
app = Application()
for route in self.routes:
app.router.add_route(route.method, route.path, route.handler)
logger.info("Registered HTTP route: {} {}", route.method, route.path)
self._app_runner = AppRunner(app)
await self._app_runner.setup()
self._site = TCPSite(self._app_runner, self.settings.http_host, self.settings.http_port)
async def start(self: Self) -> None:
await self._site.start()
async def stop(self: Self) -> None:
await self._app_runner.cleanup()
@property
def name(self: Self) -> str:
return "http_server"
class HTTPServerResource(AsyncResource):
async def init(self: Self, settings: Settings, controllers: Sequence[ControllerBase]) -> HTTPServer:
routes = tuple(chain.from_iterable(controller.get_routes()
for controller
in controllers))
http_server = HTTPServer(settings=settings, routes=routes)
await http_server.initialize()
return http_server
async def shutdown(self: Self, http_server: HTTPServer) -> None:
await http_server.stop()