comfyui-workflow-templates-core 0.3.46__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,9 @@
1
+ Metadata-Version: 2.4
2
+ Name: comfyui-workflow-templates-core
3
+ Version: 0.3.46
4
+ Summary: Core helpers for ComfyUI workflow templates
5
+ License-Expression: MIT
6
+ Requires-Python: >=3.9
7
+ Description-Content-Type: text/plain
8
+
9
+ Core helpers for ComfyUI workflow templates.
@@ -0,0 +1,17 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "comfyui-workflow-templates-core"
7
+ version = "0.3.46"
8
+ description = "Core helpers for ComfyUI workflow templates"
9
+ readme = {text = "Core helpers for ComfyUI workflow templates.", content-type = "text/plain"}
10
+ requires-python = ">=3.9"
11
+ license = "MIT"
12
+
13
+ [tool.setuptools.packages.find]
14
+ where = ["src"]
15
+
16
+ [tool.setuptools.package-data]
17
+ comfyui_workflow_templates_core = ["manifest.json"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,25 @@
1
+ """
2
+ Core runtime helpers for ComfyUI workflow templates.
3
+
4
+ This package is responsible for loading the manifest, resolving asset
5
+ paths across media bundles, and exposing metadata that higher-level
6
+ packages (e.g., the meta wrapper or ComfyUI itself) can consume.
7
+ """
8
+
9
+ from .loader import (
10
+ get_asset_path,
11
+ get_template_entry,
12
+ iter_assets,
13
+ iter_templates,
14
+ load_manifest,
15
+ resolve_all_assets,
16
+ )
17
+
18
+ __all__ = [
19
+ "get_asset_path",
20
+ "get_template_entry",
21
+ "iter_assets",
22
+ "iter_templates",
23
+ "load_manifest",
24
+ "resolve_all_assets",
25
+ ]
@@ -0,0 +1,129 @@
1
+ """
2
+ Manifest loader and asset resolution helpers.
3
+
4
+ The manifest is generated during the build step and embedded as package
5
+ data in `comfyui_workflow_templates_core`. Each media bundle exposes its
6
+ assets under a namespace package (e.g., `comfyui_workflow_templates_media_api`).
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import json
12
+ from dataclasses import dataclass
13
+ from functools import lru_cache
14
+ from importlib import resources
15
+ from typing import Dict, Iterable, Iterator, List, Tuple
16
+
17
+ MANIFEST_RESOURCE = "manifest.json"
18
+
19
+ BUNDLE_PACKAGE_MAP = {
20
+ "media-api": "comfyui_workflow_templates_media_api",
21
+ "media-video": "comfyui_workflow_templates_media_video",
22
+ "media-image": "comfyui_workflow_templates_media_image",
23
+ "media-other": "comfyui_workflow_templates_media_other",
24
+ }
25
+
26
+
27
+ @dataclass(frozen=True)
28
+ class TemplateAsset:
29
+ filename: str
30
+ sha256: str
31
+
32
+
33
+ @dataclass(frozen=True)
34
+ class TemplateEntry:
35
+ template_id: str
36
+ bundle: str
37
+ version: str
38
+ assets: List[TemplateAsset]
39
+
40
+
41
+ @dataclass(frozen=True)
42
+ class Manifest:
43
+ manifest_version: int
44
+ bundles: Dict[str, Dict[str, str]]
45
+ templates: Dict[str, TemplateEntry]
46
+
47
+
48
+ def _parse_manifest(payload: str) -> Manifest:
49
+ raw = json.loads(payload)
50
+ templates: Dict[str, TemplateEntry] = {}
51
+ for entry in raw.get("templates", []):
52
+ assets = [
53
+ TemplateAsset(a["filename"], a["sha256"])
54
+ for a in entry.get("assets", [])
55
+ ]
56
+ templates[entry["id"]] = TemplateEntry(
57
+ template_id=entry["id"],
58
+ bundle=entry["bundle"],
59
+ version=entry.get("version", ""),
60
+ assets=assets,
61
+ )
62
+ return Manifest(
63
+ manifest_version=raw.get("manifest_version", 1),
64
+ bundles=raw.get("bundles", {}),
65
+ templates=templates,
66
+ )
67
+
68
+
69
+ @lru_cache(maxsize=1)
70
+ def load_manifest() -> Manifest:
71
+ """Load and cache the manifest from package data."""
72
+ data = resources.files(__package__).joinpath(MANIFEST_RESOURCE).read_text()
73
+ return _parse_manifest(data)
74
+
75
+
76
+ def iter_templates() -> Iterable[TemplateEntry]:
77
+ """Iterate over all template entries."""
78
+ return load_manifest().templates.values()
79
+
80
+
81
+ def get_template_entry(template_id: str) -> TemplateEntry:
82
+ """Return manifest entry for the given template id."""
83
+ try:
84
+ return load_manifest().templates[template_id]
85
+ except KeyError as exc:
86
+ raise KeyError(f"Template '{template_id}' not found in manifest") from exc
87
+
88
+
89
+ def _bundle_package(bundle_name: str) -> str:
90
+ try:
91
+ return BUNDLE_PACKAGE_MAP[bundle_name]
92
+ except KeyError as exc:
93
+ raise KeyError(f"No package mapping defined for bundle '{bundle_name}'") from exc
94
+
95
+
96
+ def get_asset_path(template_id: str, filename: str) -> str:
97
+ """
98
+ Resolve the absolute path for an asset belonging to `template_id`.
99
+
100
+ Raises:
101
+ FileNotFoundError: if the bundle package or asset is missing.
102
+ """
103
+ entry = get_template_entry(template_id)
104
+ package_name = _bundle_package(entry.bundle)
105
+ try:
106
+ package_files = resources.files(package_name)
107
+ except ModuleNotFoundError as exc:
108
+ raise FileNotFoundError(
109
+ f"Media package '{package_name}' is not installed for bundle '{entry.bundle}'"
110
+ ) from exc
111
+ asset = package_files / "templates" / filename
112
+ if not asset.exists():
113
+ raise FileNotFoundError(
114
+ f"Asset '{filename}' for template '{template_id}' not found in package '{package_name}'"
115
+ )
116
+ return str(asset)
117
+
118
+
119
+ def resolve_all_assets(template_id: str) -> List[str]:
120
+ """Return absolute paths for every asset declared for the template."""
121
+ entry = get_template_entry(template_id)
122
+ return [get_asset_path(template_id, asset.filename) for asset in entry.assets]
123
+
124
+
125
+ def iter_assets() -> Iterator[Tuple[str, str]]:
126
+ """Yield tuples of (relative_filename, absolute_path) for every asset."""
127
+ for entry in iter_templates():
128
+ for asset in entry.assets:
129
+ yield asset.filename, get_asset_path(entry.template_id, asset.filename)