Skip to content

Commit 69a5047

Browse files
jazzhaikupsychedelicious
authored andcommitted
More detailed error messages
1 parent 842b770 commit 69a5047

File tree

3 files changed

+114
-3
lines changed

3 files changed

+114
-3
lines changed

invokeai/app/invocations/metadata.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -287,14 +287,16 @@ class MetadataFieldExtractorInvocation(BaseInvocation):
287287
key: str = InputField(description="The key in the image's metadata to extract the value from")
288288

289289
def invoke(self, context: InvocationContext) -> StringOutput:
290-
metadata = context.images.get_metadata(image_name=self.image.image_name)
290+
image_name = self.image.image_name
291+
292+
metadata = context.images.get_metadata(image_name=image_name)
291293
if not metadata:
292-
raise ValueError("No metadata found on image")
294+
raise ValueError(f"No metadata found on image {image_name}")
293295

294296
try:
295297
val = metadata.root[self.key]
296298
if not isinstance(val, str):
297299
raise ValueError(f"Metadata at key '{self.key}' must be a string")
298300
return StringOutput(value=val)
299301
except KeyError as e:
300-
raise ValueError(f"No key {self.key} found in metadata") from e
302+
raise ValueError(f"No key '{self.key}' found in the metadata for {image_name}") from e

nodes/README.md

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# Custom Nodes / Node Packs
2+
3+
Copy your node packs to this directory.
4+
5+
When nodes are added or changed, you must restart the app to see the changes.
6+
7+
## Directory Structure
8+
9+
For a node pack to be loaded, it must be placed in a directory alongside this
10+
file. Here's an example structure:
11+
12+
```py
13+
.
14+
├── __init__.py # Invoke-managed custom node loader
15+
16+
├── cool_node
17+
│ ├── __init__.py # see example below
18+
│ └── cool_node.py
19+
20+
└── my_node_pack
21+
├── __init__.py # see example below
22+
├── tasty_node.py
23+
├── bodacious_node.py
24+
├── utils.py
25+
└── extra_nodes
26+
└── fancy_node.py
27+
```
28+
29+
## Node Pack `__init__.py`
30+
31+
Each node pack must have an `__init__.py` file that imports its nodes.
32+
33+
The structure of each node or node pack is otherwise not important.
34+
35+
Here are examples, based on the example directory structure.
36+
37+
### `cool_node/__init__.py`
38+
39+
```py
40+
from .cool_node import CoolInvocation
41+
```
42+
43+
### `my_node_pack/__init__.py`
44+
45+
```py
46+
from .tasty_node import TastyInvocation
47+
from .bodacious_node import BodaciousInvocation
48+
from .extra_nodes.fancy_node import FancyInvocation
49+
```
50+
51+
Only nodes imported in the `__init__.py` file are loaded.

nodes/__init__.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
"""
2+
Invoke-managed custom node loader. See README.md for more information.
3+
"""
4+
5+
import sys
6+
import traceback
7+
from importlib.util import module_from_spec, spec_from_file_location
8+
from pathlib import Path
9+
10+
from invokeai.backend.util.logging import InvokeAILogger
11+
12+
logger = InvokeAILogger.get_logger()
13+
loaded_count = 0
14+
15+
16+
for d in Path(__file__).parent.iterdir():
17+
# skip files
18+
if not d.is_dir():
19+
continue
20+
21+
# skip hidden directories
22+
if d.name.startswith("_") or d.name.startswith("."):
23+
continue
24+
25+
# skip directories without an `__init__.py`
26+
init = d / "__init__.py"
27+
if not init.exists():
28+
continue
29+
30+
module_name = init.parent.stem
31+
32+
# skip if already imported
33+
if module_name in globals():
34+
continue
35+
36+
# load the module, appending adding a suffix to identify it as a custom node pack
37+
spec = spec_from_file_location(module_name, init.absolute())
38+
39+
if spec is None or spec.loader is None:
40+
logger.warn(f"Could not load {init}")
41+
continue
42+
43+
logger.info(f"Loading node pack {module_name}")
44+
45+
try:
46+
module = module_from_spec(spec)
47+
sys.modules[spec.name] = module
48+
spec.loader.exec_module(module)
49+
50+
loaded_count += 1
51+
except Exception:
52+
full_error = traceback.format_exc()
53+
logger.error(f"Failed to load node pack {module_name}:\n{full_error}")
54+
55+
del init, module_name
56+
57+
if loaded_count > 0:
58+
logger.info(f"Loaded {loaded_count} node packs from {Path(__file__).parent}")

0 commit comments

Comments
 (0)