|
62 | 62 | ] |
63 | 63 |
|
64 | 64 | SUPPORTED_WRITERS: dict = {} |
| 65 | +WRITER_DEPENDENCY_HINTS: dict[type, tuple[str, str]] = {} |
65 | 66 |
|
66 | 67 |
|
67 | 68 | def register_writer(ext_name, *im_writers): |
@@ -106,17 +107,34 @@ def resolve_writer(ext_name, error_if_not_found=True) -> Sequence: |
106 | 107 | if fmt.startswith("."): |
107 | 108 | fmt = fmt[1:] |
108 | 109 | avail_writers = [] |
| 110 | + dependency_hints: set[tuple[str, str]] = set() |
109 | 111 | default_writers = SUPPORTED_WRITERS.get(EXT_WILDCARD, ()) |
110 | 112 | for _writer in look_up_option(fmt, SUPPORTED_WRITERS, default=default_writers): |
111 | 113 | try: |
112 | 114 | _writer() # this triggers `monai.utils.module.require_pkg` to check the system availability |
113 | 115 | avail_writers.append(_writer) |
114 | 116 | except OptionalImportError: |
| 117 | + hint = WRITER_DEPENDENCY_HINTS.get(_writer) |
| 118 | + if hint: |
| 119 | + dependency_hints.add(hint) |
115 | 120 | continue |
116 | 121 | except Exception: # other writer init errors indicating it exists |
117 | 122 | avail_writers.append(_writer) |
118 | 123 | if not avail_writers and error_if_not_found: |
119 | | - raise OptionalImportError(f"No ImageWriter backend found for {fmt}.") |
| 124 | + hint_msg = "" |
| 125 | + if dependency_hints: |
| 126 | + sorted_hints = sorted(dependency_hints, key=lambda item: item[0].lower()) |
| 127 | + if len(sorted_hints) == 1: |
| 128 | + pkg, cmd = sorted_hints[0] |
| 129 | + hint_msg = f" Install `{pkg}` (e.g. `{cmd}`) to enable writing {fmt} images." |
| 130 | + else: |
| 131 | + pkg_names = ", ".join(f"`{pkg}`" for pkg, _ in sorted_hints) |
| 132 | + commands = ", ".join(f"`{cmd}`" for _, cmd in sorted_hints) |
| 133 | + hint_msg = ( |
| 134 | + f" Install one of the supported dependencies {pkg_names} " |
| 135 | + f"(for example: {commands}) to enable writing {fmt} images." |
| 136 | + ) |
| 137 | + raise OptionalImportError(f"No ImageWriter backend found for {fmt}.{hint_msg}") |
120 | 138 | writer_tuple = ensure_tuple(avail_writers) |
121 | 139 | SUPPORTED_WRITERS[fmt] = writer_tuple |
122 | 140 | return writer_tuple |
@@ -862,6 +880,15 @@ def create_backend_obj( |
862 | 880 | return PILImage.fromarray(data, mode=kwargs.pop("image_mode", None)) |
863 | 881 |
|
864 | 882 |
|
| 883 | +WRITER_DEPENDENCY_HINTS.update( |
| 884 | + { |
| 885 | + ITKWriter: ("ITK", "pip install itk"), |
| 886 | + NibabelWriter: ("Nibabel", "pip install nibabel"), |
| 887 | + PILWriter: ("Pillow", "pip install pillow"), |
| 888 | + } |
| 889 | +) |
| 890 | + |
| 891 | + |
865 | 892 | def init(): |
866 | 893 | """ |
867 | 894 | Initialize the image writer modules according to the filename extension. |
|
0 commit comments