1010from dataclasses import dataclass
1111from functools import cached_property
1212from pathlib import Path
13- from typing import TypedDict , Optional
13+ from typing import Dict , TypedDict , Optional
14+ from aiohttp import web
1415from importlib .metadata import version
1516
1617import requests
@@ -257,7 +258,54 @@ def default_frontend_path(cls) -> str:
257258 sys .exit (- 1 )
258259
259260 @classmethod
260- def templates_path (cls ) -> str :
261+ def template_asset_map (cls ) -> Optional [Dict [str , str ]]:
262+ """Return a mapping of template asset names to their absolute paths."""
263+ try :
264+ from comfyui_workflow_templates import (
265+ get_asset_path ,
266+ iter_templates ,
267+ )
268+ except ImportError :
269+ logging .error (
270+ f"""
271+ ********** ERROR ***********
272+
273+ comfyui-workflow-templates is not installed.
274+
275+ { frontend_install_warning_message ()}
276+
277+ ********** ERROR ***********
278+ """ .strip ()
279+ )
280+ return None
281+
282+ try :
283+ template_entries = list (iter_templates ())
284+ except Exception as exc :
285+ logging .error (f"Failed to enumerate workflow templates: { exc } " )
286+ return None
287+
288+ asset_map : Dict [str , str ] = {}
289+ try :
290+ for entry in template_entries :
291+ for asset in entry .assets :
292+ asset_map [asset .filename ] = get_asset_path (
293+ entry .template_id , asset .filename
294+ )
295+ except Exception as exc :
296+ logging .error (f"Failed to resolve template asset paths: { exc } " )
297+ return None
298+
299+ if not asset_map :
300+ logging .error ("No workflow template assets found. Did the packages install correctly?" )
301+ return None
302+
303+ return asset_map
304+
305+
306+ @classmethod
307+ def legacy_templates_path (cls ) -> Optional [str ]:
308+ """Return the legacy templates directory shipped inside the meta package."""
261309 try :
262310 import comfyui_workflow_templates
263311
@@ -276,6 +324,7 @@ def templates_path(cls) -> str:
276324********** ERROR ***********
277325""" .strip ()
278326 )
327+ return None
279328
280329 @classmethod
281330 def embedded_docs_path (cls ) -> str :
@@ -392,3 +441,17 @@ def init_frontend(cls, version_string: str) -> str:
392441 logging .info ("Falling back to the default frontend." )
393442 check_frontend_version ()
394443 return cls .default_frontend_path ()
444+ @classmethod
445+ def template_asset_handler (cls ):
446+ assets = cls .template_asset_map ()
447+ if not assets :
448+ return None
449+
450+ async def serve_template (request : web .Request ) -> web .StreamResponse :
451+ rel_path = request .match_info .get ("path" , "" )
452+ target = assets .get (rel_path )
453+ if target is None :
454+ raise web .HTTPNotFound ()
455+ return web .FileResponse (target )
456+
457+ return serve_template
0 commit comments