refactor: introduce RouteContext for route dependency registration
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
"""Dependency container shared by route registration modules."""
|
||||
|
||||
from collections.abc import Mapping
|
||||
from dataclasses import dataclass
|
||||
from types import MappingProxyType
|
||||
from typing import Any
|
||||
|
||||
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class RouteContext:
|
||||
"""Immutable, read-only collection of dependencies used by API routes."""
|
||||
|
||||
_values: Mapping[str, Any]
|
||||
|
||||
def __post_init__(self):
|
||||
object.__setattr__(
|
||||
self,
|
||||
"_values",
|
||||
MappingProxyType(dict(self._values)),
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def from_namespaces(
|
||||
cls,
|
||||
*namespaces: Mapping[str, Any],
|
||||
) -> "RouteContext":
|
||||
"""Build a context, with later namespaces taking precedence."""
|
||||
values = {}
|
||||
for namespace in namespaces:
|
||||
values.update(namespace)
|
||||
return cls(values)
|
||||
|
||||
def get(self, key: str, default: Any = None) -> Any:
|
||||
"""Return a dependency or the supplied default when it is optional."""
|
||||
return self._values.get(key, default)
|
||||
|
||||
def require(self, key: str) -> Any:
|
||||
"""Return a dependency or fail with a descriptive configuration error."""
|
||||
try:
|
||||
return self._values[key]
|
||||
except KeyError as exc:
|
||||
raise KeyError(f"Missing route dependency: {key}") from exc
|
||||
|
||||
def __contains__(self, key: str) -> bool:
|
||||
return key in self._values
|
||||
|
||||
def __len__(self) -> int:
|
||||
return len(self._values)
|
||||
@@ -1,6 +1,9 @@
|
||||
"""Directories route registration."""
|
||||
|
||||
def register_directory_routes(context):
|
||||
from .context import RouteContext
|
||||
|
||||
|
||||
def register_directory_routes(context: RouteContext):
|
||||
TEMPLATE_KEY_ALIASES = context.get('TEMPLATE_KEY_ALIASES')
|
||||
asyncio = context.get('asyncio')
|
||||
dedupe_local_base_directories = context.get('dedupe_local_base_directories')
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
"""Downloads route registration."""
|
||||
|
||||
def register_download_routes(context):
|
||||
from .context import RouteContext
|
||||
|
||||
|
||||
def register_download_routes(context: RouteContext):
|
||||
Aria2InstallError = context.get('Aria2InstallError')
|
||||
UnsafeUrlError = context.get('UnsafeUrlError')
|
||||
asyncio = context.get('asyncio')
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
"""Metadata route registration."""
|
||||
|
||||
def register_metadata_routes(context):
|
||||
from .context import RouteContext
|
||||
|
||||
|
||||
def register_metadata_routes(context: RouteContext):
|
||||
asyncio = context.get('asyncio')
|
||||
audit_metadata_sizes = context.get('audit_metadata_sizes')
|
||||
build_missing_local_metadata = context.get('build_missing_local_metadata')
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
"""Model Info route registration."""
|
||||
|
||||
def register_model_info_routes(context):
|
||||
from .context import RouteContext
|
||||
|
||||
|
||||
def register_model_info_routes(context: RouteContext):
|
||||
UnsafeUrlError = context.get('UnsafeUrlError')
|
||||
asyncio = context.get('asyncio')
|
||||
build_civarchive_custom_result = context.get('build_civarchive_custom_result')
|
||||
|
||||
@@ -20,6 +20,7 @@ from ..path_utils import (
|
||||
get_model_resolver_sidecar_path,
|
||||
get_safe_model_resolver_sidecar_path,
|
||||
)
|
||||
from .context import RouteContext
|
||||
|
||||
|
||||
def register_routes(self):
|
||||
@@ -240,7 +241,7 @@ def register_routes(self):
|
||||
)
|
||||
|
||||
register_base_model_routes(routes, web, json_api_endpoint)
|
||||
route_context = {**globals(), **locals()}
|
||||
route_context = RouteContext.from_namespaces(globals(), locals())
|
||||
register_workflow_routes(route_context)
|
||||
register_metadata_routes(route_context)
|
||||
register_loaded_model_routes(route_context)
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
"""Search route registration."""
|
||||
|
||||
def register_search_routes(context):
|
||||
from .context import RouteContext
|
||||
|
||||
|
||||
def register_search_routes(context: RouteContext):
|
||||
CivArchiveSearchError = context.get('CivArchiveSearchError')
|
||||
asyncio = context.get('asyncio')
|
||||
build_search_result = context.get('build_search_result')
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
"""Workflow and loaded-model route registration."""
|
||||
|
||||
def register_workflow_routes(context):
|
||||
from .context import RouteContext
|
||||
|
||||
|
||||
def register_workflow_routes(context: RouteContext):
|
||||
FileManagerError = context.get('FileManagerError')
|
||||
FileManagerUnavailableError = context.get('FileManagerUnavailableError')
|
||||
MODEL_RESOLVER_METADATA_SCHEMA = context.get('MODEL_RESOLVER_METADATA_SCHEMA')
|
||||
@@ -914,7 +917,7 @@ def register_workflow_routes(context):
|
||||
cancel_message="Stopping hash calculation..."
|
||||
)
|
||||
|
||||
def register_loaded_model_routes(context):
|
||||
def register_loaded_model_routes(context: RouteContext):
|
||||
adapt_custom_node_loaded_model = context.get('adapt_custom_node_loaded_model')
|
||||
asyncio = context.get('asyncio')
|
||||
get_filename_from_path = context.get('get_filename_from_path')
|
||||
|
||||
@@ -245,6 +245,27 @@ class TestRefactoringTargets(unittest.IsolatedAsyncioTestCase):
|
||||
self.assertEqual(node_mod._version_sort_key("v1.10.2-beta"), (1, 10, 2))
|
||||
self.assertEqual(node_mod._version_sort_key("unknown"), ())
|
||||
|
||||
def test_route_context_merges_namespaces_and_validates_required_values(self):
|
||||
context_module = importlib.import_module(
|
||||
"comfyui-model-resolver.core.routes.context"
|
||||
)
|
||||
values = {"shared": "first", "left": 1}
|
||||
context = context_module.RouteContext.from_namespaces(
|
||||
values,
|
||||
{"shared": "second", "right": 2},
|
||||
)
|
||||
values["left"] = 99
|
||||
|
||||
self.assertEqual(context.get("shared"), "second")
|
||||
self.assertEqual(context.get("left"), 1)
|
||||
self.assertEqual(context.get("missing"), None)
|
||||
self.assertEqual(context.get("missing", "fallback"), "fallback")
|
||||
self.assertEqual(context.require("right"), 2)
|
||||
self.assertIn("right", context)
|
||||
self.assertEqual(len(context), 3)
|
||||
with self.assertRaisesRegex(KeyError, "Missing route dependency: missing"):
|
||||
context.require("missing")
|
||||
|
||||
def test_project_version_info_reports_remote_update(self):
|
||||
version_module = importlib.import_module("comfyui-model-resolver.core.version")
|
||||
network_module = importlib.import_module("comfyui-model-resolver.core.network_utils")
|
||||
|
||||
Reference in New Issue
Block a user