mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-03-21 21:22:11 -03:00
Merge pull request #455 from willmiao/codex/refactor-reciperoutes-into-handler-objects
refactor: split recipe routes into dedicated handlers
This commit is contained in:
@@ -11,6 +11,15 @@ from ..config import config
|
||||
from ..services.server_i18n import server_i18n
|
||||
from ..services.service_registry import ServiceRegistry
|
||||
from ..services.settings_manager import settings
|
||||
from .handlers.recipe_handlers import (
|
||||
RecipeAnalysisHandler,
|
||||
RecipeHandlerSet,
|
||||
RecipeListingHandler,
|
||||
RecipeManagementHandler,
|
||||
RecipePageView,
|
||||
RecipeQueryHandler,
|
||||
RecipeSharingHandler,
|
||||
)
|
||||
from .recipe_route_registrar import ROUTE_DEFINITIONS
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -23,6 +32,8 @@ class BaseRecipeRoutes:
|
||||
definition.handler_name for definition in ROUTE_DEFINITIONS
|
||||
)
|
||||
|
||||
template_name: str = "recipes.html"
|
||||
|
||||
def __init__(self) -> None:
|
||||
self.recipe_scanner = None
|
||||
self.lora_scanner = None
|
||||
@@ -36,6 +47,7 @@ class BaseRecipeRoutes:
|
||||
|
||||
self._i18n_registered = False
|
||||
self._startup_hooks_registered = False
|
||||
self._handler_set: RecipeHandlerSet | None = None
|
||||
self._handler_mapping: dict[str, Callable] | None = None
|
||||
|
||||
async def attach_dependencies(self, app: web.Application | None = None) -> None:
|
||||
@@ -81,10 +93,9 @@ class BaseRecipeRoutes:
|
||||
"""Return a mapping of handler name to coroutine for registrar binding."""
|
||||
|
||||
if self._handler_mapping is None:
|
||||
owner = self.get_handler_owner()
|
||||
self._handler_mapping = {
|
||||
name: getattr(owner, name) for name in self._HANDLER_NAMES
|
||||
}
|
||||
handler_set = self._create_handler_set()
|
||||
self._handler_set = handler_set
|
||||
self._handler_mapping = handler_set.to_route_mapping()
|
||||
return self._handler_mapping
|
||||
|
||||
# Internal helpers -------------------------------------------------
|
||||
@@ -105,5 +116,57 @@ class BaseRecipeRoutes:
|
||||
def get_handler_owner(self):
|
||||
"""Return the object supplying bound handler coroutines."""
|
||||
|
||||
return self
|
||||
if self._handler_set is None:
|
||||
self._handler_set = self._create_handler_set()
|
||||
return self._handler_set
|
||||
|
||||
def _create_handler_set(self) -> RecipeHandlerSet:
|
||||
recipe_scanner_getter = lambda: self.recipe_scanner
|
||||
civitai_client_getter = lambda: self.civitai_client
|
||||
|
||||
page_view = RecipePageView(
|
||||
ensure_dependencies_ready=self.ensure_dependencies_ready,
|
||||
settings_service=self.settings,
|
||||
server_i18n=self.server_i18n,
|
||||
template_env=self.template_env,
|
||||
template_name=self.template_name,
|
||||
recipe_scanner_getter=recipe_scanner_getter,
|
||||
logger=logger,
|
||||
)
|
||||
listing = RecipeListingHandler(
|
||||
ensure_dependencies_ready=self.ensure_dependencies_ready,
|
||||
recipe_scanner_getter=recipe_scanner_getter,
|
||||
logger=logger,
|
||||
)
|
||||
query = RecipeQueryHandler(
|
||||
ensure_dependencies_ready=self.ensure_dependencies_ready,
|
||||
recipe_scanner_getter=recipe_scanner_getter,
|
||||
format_recipe_file_url=listing.format_recipe_file_url,
|
||||
logger=logger,
|
||||
)
|
||||
management = RecipeManagementHandler(
|
||||
ensure_dependencies_ready=self.ensure_dependencies_ready,
|
||||
recipe_scanner_getter=recipe_scanner_getter,
|
||||
logger=logger,
|
||||
)
|
||||
analysis = RecipeAnalysisHandler(
|
||||
ensure_dependencies_ready=self.ensure_dependencies_ready,
|
||||
recipe_scanner_getter=recipe_scanner_getter,
|
||||
civitai_client_getter=civitai_client_getter,
|
||||
logger=logger,
|
||||
)
|
||||
sharing = RecipeSharingHandler(
|
||||
ensure_dependencies_ready=self.ensure_dependencies_ready,
|
||||
recipe_scanner_getter=recipe_scanner_getter,
|
||||
logger=logger,
|
||||
)
|
||||
|
||||
return RecipeHandlerSet(
|
||||
page_view=page_view,
|
||||
listing=listing,
|
||||
query=query,
|
||||
management=management,
|
||||
analysis=analysis,
|
||||
sharing=sharing,
|
||||
)
|
||||
|
||||
|
||||
1347
py/routes/handlers/recipe_handlers.py
Normal file
1347
py/routes/handlers/recipe_handlers.py
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -128,31 +128,38 @@ def test_register_startup_hooks_appends_once():
|
||||
assert len(startup_bound_to_routes) == 2
|
||||
|
||||
|
||||
def test_to_route_mapping_uses_handler_owner(monkeypatch: pytest.MonkeyPatch):
|
||||
class DummyOwner:
|
||||
async def render_page(self, request):
|
||||
return web.Response(text="ok")
|
||||
def test_to_route_mapping_uses_handler_set():
|
||||
class DummyHandlerSet:
|
||||
def __init__(self):
|
||||
self.calls = 0
|
||||
|
||||
async def list_recipes(self, request): # pragma: no cover - invoked via mapping
|
||||
return web.json_response({})
|
||||
def to_route_mapping(self):
|
||||
self.calls += 1
|
||||
|
||||
async def render_page(request): # pragma: no cover - simple coroutine
|
||||
return web.Response(text="ok")
|
||||
|
||||
return {"render_page": render_page}
|
||||
|
||||
class DummyRoutes(base_routes_module.BaseRecipeRoutes):
|
||||
def get_handler_owner(self): # noqa: D401 - simple override for test
|
||||
return DummyOwner()
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.created = 0
|
||||
|
||||
monkeypatch.setattr(
|
||||
base_routes_module.BaseRecipeRoutes,
|
||||
"_HANDLER_NAMES",
|
||||
("render_page", "list_recipes"),
|
||||
)
|
||||
def _create_handler_set(self): # noqa: D401 - simple override for test
|
||||
self.created += 1
|
||||
return DummyHandlerSet()
|
||||
|
||||
routes = DummyRoutes()
|
||||
mapping = routes.to_route_mapping()
|
||||
|
||||
assert set(mapping.keys()) == {"render_page", "list_recipes"}
|
||||
assert set(mapping.keys()) == {"render_page"}
|
||||
assert asyncio.iscoroutinefunction(mapping["render_page"])
|
||||
# Cached mapping reused on subsequent calls
|
||||
assert routes.to_route_mapping() is mapping
|
||||
# Handler set cached for get_handler_owner callers
|
||||
assert isinstance(routes.get_handler_owner(), DummyHandlerSet)
|
||||
assert routes.created == 1
|
||||
|
||||
|
||||
def test_recipe_route_registrar_binds_every_route():
|
||||
|
||||
Reference in New Issue
Block a user