Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

6834 Add MetaProterties and update load API #6835

Merged
merged 70 commits into from
Aug 30, 2023
Merged
Show file tree
Hide file tree
Changes from 59 commits
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
faa8dc6
add `AutoBundle` and `from_bundle`
KumoLiu Aug 8, 2023
efcb485
Merge remote-tracking branch 'origin/dev' into from-bundle
KumoLiu Aug 8, 2023
be7aa45
minor fix
KumoLiu Aug 8, 2023
e83478a
Merge branch 'dev' into from-bundle
KumoLiu Aug 8, 2023
7c26f75
Merge branch 'dev' into from-bundle
KumoLiu Aug 10, 2023
a7bc4e8
rename to `BundleManager`
KumoLiu Aug 10, 2023
5dc2f4e
Merge branch 'from-bundle' of https://github.com/KumoLiu/MONAI into f…
KumoLiu Aug 10, 2023
b8bc55a
support multi configs
KumoLiu Aug 10, 2023
eb6a9d4
add docstring
KumoLiu Aug 10, 2023
fc677b5
change `bundle_name_or_path`
KumoLiu Aug 11, 2023
e312186
Merge branch 'dev' into from-bundle
KumoLiu Aug 11, 2023
8fb5076
support flexible postfix
KumoLiu Aug 11, 2023
e4d061f
minor fix
KumoLiu Aug 11, 2023
d49f3d0
minor fix
KumoLiu Aug 11, 2023
dc8858b
update based on comments
KumoLiu Aug 11, 2023
cc5c2c7
fix flake8
KumoLiu Aug 11, 2023
52c9f52
update docstring
KumoLiu Aug 11, 2023
5eec914
update based on comments
KumoLiu Aug 13, 2023
42bac3d
fix flake8
KumoLiu Aug 13, 2023
1623a6d
Merge branch 'dev' of https://github.com/Project-MONAI/MONAI into fro…
KumoLiu Aug 14, 2023
0903997
rename `bundle_name` to `name`
KumoLiu Aug 14, 2023
6576c15
update docstring
KumoLiu Aug 14, 2023
0409cac
add `MetaProterties`
KumoLiu Aug 15, 2023
7057fe2
support getting meta property
KumoLiu Aug 23, 2023
5b484ec
Merge branch 'dev' of https://github.com/Project-MONAI/MONAI into fro…
KumoLiu Aug 23, 2023
7ab0a74
remove `BundleManager`
KumoLiu Aug 23, 2023
79bf87d
simplify the specification for
KumoLiu Aug 23, 2023
1a2abea
fix flake8
KumoLiu Aug 23, 2023
a8ae128
fix mypy
KumoLiu Aug 23, 2023
c0c4e01
simplify the specification for
KumoLiu Aug 23, 2023
fcc8b1b
add `create_workflow` and update `load`
KumoLiu Aug 23, 2023
30ebb16
remove `_find_config_file`
KumoLiu Aug 23, 2023
f609f98
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Aug 23, 2023
ee525f8
update docstring
KumoLiu Aug 23, 2023
a9a1163
Merge branch 'from-bundle' of https://github.com/KumoLiu/MONAI into f…
KumoLiu Aug 23, 2023
83cd3d3
minor fix
KumoLiu Aug 24, 2023
559711d
add unittests for load
KumoLiu Aug 24, 2023
7038b90
update the docstring for the `load`
KumoLiu Aug 24, 2023
a5992b9
fix flake8
KumoLiu Aug 24, 2023
0531989
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Aug 24, 2023
a5cfd71
fix mypy
KumoLiu Aug 24, 2023
2229c4d
Merge branch 'from-bundle' of https://github.com/KumoLiu/MONAI into f…
KumoLiu Aug 24, 2023
82a3c23
fix ci
KumoLiu Aug 24, 2023
0ad2364
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Aug 24, 2023
6938718
fix ci
KumoLiu Aug 24, 2023
5da4ea6
Update monai/bundle/__init__.py
KumoLiu Aug 25, 2023
85275d3
fix typo
KumoLiu Aug 25, 2023
63d3a84
update according to comments
KumoLiu Aug 25, 2023
864dadb
fix flake8
KumoLiu Aug 25, 2023
fa3b940
Update monai/bundle/workflows.py
KumoLiu Aug 25, 2023
54c65af
minor fix
KumoLiu Aug 25, 2023
384ff08
Merge branch 'from-bundle' of https://github.com/KumoLiu/MONAI into f…
KumoLiu Aug 25, 2023
c4ac467
fix version ci error
KumoLiu Aug 28, 2023
b267d76
fix flake8
KumoLiu Aug 28, 2023
05e51e5
set "meta_file" as required in `ConfigWorkflow`
KumoLiu Aug 28, 2023
bc3a134
fix flake8
KumoLiu Aug 28, 2023
dcd76dd
minor fix
KumoLiu Aug 28, 2023
3afb12d
Merge branch 'dev' of https://github.com/Project-MONAI/MONAI into fro…
KumoLiu Aug 28, 2023
8e74d04
fix unittests
KumoLiu Aug 28, 2023
fe76258
address comments
KumoLiu Aug 29, 2023
e5c8bfd
address comments
KumoLiu Aug 29, 2023
2789c5f
fix flake8
KumoLiu Aug 29, 2023
561a68e
add deprecated_arg for `net_name`
KumoLiu Aug 30, 2023
9b6bc08
Merge branch 'dev' into from-bundle
KumoLiu Aug 30, 2023
0039860
update `worklfow` to `workflow_type`
KumoLiu Aug 30, 2023
32de5aa
Merge branch 'from-bundle' of https://github.com/KumoLiu/MONAI into f…
KumoLiu Aug 30, 2023
134d1ea
fix flake8
KumoLiu Aug 30, 2023
e93309e
fix ci
KumoLiu Aug 30, 2023
edb8768
address comments
KumoLiu Aug 30, 2023
93a149a
Merge branch 'dev' into from-bundle
wyli Aug 30, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion monai/bundle/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@

from .config_item import ComponentLocator, ConfigComponent, ConfigExpression, ConfigItem, Instantiable
from .config_parser import ConfigParser
from .properties import InferProperties, TrainProperties
from .properties import InferProperties, MetaProperties, TrainProperties
from .reference_resolver import ReferenceResolver
from .scripts import (
ckpt_export,
create_workflow,
download,
get_all_bundles_list,
get_bundle_info,
Expand Down
46 changes: 45 additions & 1 deletion monai/bundle/properties.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
to interact with the bundle workflow.
Some properties are required and some are optional, optional properties mean: if some component of the
bundle workflow refer to the property, the property must be defined, otherwise, the property can be None.
Every item in this `TrainProperties` or `InferProperties` dictionary is a property,
Every item in this `TrainProperties` or `InferProperties` or `MetaProperties` dictionary is a property,
the key is the property name and the values include:
1. description.
2. whether it's a required property.
Expand Down Expand Up @@ -48,6 +48,11 @@
BundleProperty.REQUIRED: True,
BundlePropertyConfig.ID: f"train{ID_SEP_KEY}trainer",
},
"network_def": {
Nic-Ma marked this conversation as resolved.
Show resolved Hide resolved
BundleProperty.DESC: "network module for the training.",
BundleProperty.REQUIRED: False,
BundlePropertyConfig.ID: "network_def",
},
"max_epochs": {
BundleProperty.DESC: "max number of epochs to execute the training.",
BundleProperty.REQUIRED: True,
Expand Down Expand Up @@ -216,3 +221,42 @@
BundlePropertyConfig.REF_ID: f"evaluator{ID_SEP_KEY}key_val_metric",
},
}

MetaProperties = {
"version": {
BundleProperty.DESC: "bundle version",
BundleProperty.REQUIRED: True,
BundlePropertyConfig.ID: f"_meta_{ID_SEP_KEY}version",
},
"monai_version": {
BundleProperty.DESC: "required monai version used for bundle",
BundleProperty.REQUIRED: True,
BundlePropertyConfig.ID: f"_meta_{ID_SEP_KEY}monai_version",
},
"pytorch_version": {
BundleProperty.DESC: "required pytorch version used for bundle",
BundleProperty.REQUIRED: True,
BundlePropertyConfig.ID: f"_meta_{ID_SEP_KEY}pytorch_version",
},
"numpy_version": {
BundleProperty.DESC: "required numpy version used for bundle",
BundleProperty.REQUIRED: True,
BundlePropertyConfig.ID: f"_meta_{ID_SEP_KEY}numpy_version",
},
"description": {
BundleProperty.DESC: "description for bundle",
BundleProperty.REQUIRED: False,
BundlePropertyConfig.ID: f"_meta_{ID_SEP_KEY}description",
},
"spatial_shape": {
Nic-Ma marked this conversation as resolved.
Show resolved Hide resolved
BundleProperty.DESC: "spatial shape for the inputs",
BundleProperty.REQUIRED: False,
BundlePropertyConfig.ID: f"_meta_{ID_SEP_KEY}network_data_format{ID_SEP_KEY}inputs{ID_SEP_KEY}image"
f"{ID_SEP_KEY}spatial_shape",
},
"channel_def": {
BundleProperty.DESC: "channel definition for the prediction",
BundleProperty.REQUIRED: False,
BundlePropertyConfig.ID: f"_meta_{ID_SEP_KEY}network_data_format{ID_SEP_KEY}outputs{ID_SEP_KEY}pred{ID_SEP_KEY}channel_def",
},
}
160 changes: 109 additions & 51 deletions monai/bundle/scripts.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@

from monai.apps.mmars.mmars import _get_all_ngc_models
from monai.apps.utils import _basename, download_url, extractall, get_logger
from monai.bundle.config_item import ConfigComponent
from monai.bundle.config_parser import ConfigParser
from monai.bundle.utils import DEFAULT_INFERENCE, DEFAULT_METADATA
from monai.bundle.workflows import BundleWorkflow, ConfigWorkflow
Expand Down Expand Up @@ -63,7 +62,7 @@

# set BUNDLE_DOWNLOAD_SRC="ngc" to use NGC source in default for bundle download
# set BUNDLE_DOWNLOAD_SRC="monaihosting" to use monaihosting source in default for bundle download
download_source = os.environ.get("BUNDLE_DOWNLOAD_SRC", "github")
DEFAULT_DOWNLOAD_SOURCE = os.environ.get("BUNDLE_DOWNLOAD_SRC", "github")
PPRINT_CONFIG_N = 5


Expand Down Expand Up @@ -253,7 +252,7 @@
name: str | None = None,
version: str | None = None,
bundle_dir: PathLike | None = None,
source: str = download_source,
source: str = DEFAULT_DOWNLOAD_SOURCE,
repo: str | None = None,
url: str | None = None,
remove_prefix: str | None = "monai_",
Expand Down Expand Up @@ -378,19 +377,23 @@

def load(
name: str,
model: torch.nn.Module | None = None,
version: str | None = None,
workflow: str = "train",
model_file: str | None = None,
load_ts_module: bool = False,
bundle_dir: PathLike | None = None,
source: str = download_source,
source: str = DEFAULT_DOWNLOAD_SOURCE,
repo: str | None = None,
remove_prefix: str | None = "monai_",
progress: bool = True,
device: str | None = None,
key_in_ckpt: str | None = None,
config_files: Sequence[str] = (),
net_name: str | None = None,
**net_kwargs: Any,
workflow_name: str | BundleWorkflow | None = None,
args_file: str | None = None,
copy_model_args: dict | None = None,
**net_override: Any,
) -> object | tuple[torch.nn.Module, dict, dict] | Any:
"""
Load model weights or TorchScript module of a bundle.
Expand All @@ -402,8 +405,15 @@
https://github.com/Project-MONAI/model-zoo/releases/tag/hosting_storage_v1.
"monai_brats_mri_segmentation" in ngc:
https://catalog.ngc.nvidia.com/models?filters=&orderBy=scoreDESC&query=monai.
"mednist_gan" in monaihosting:
https://api.ngc.nvidia.com/v2/models/nvidia/monaihosting/mednist_gan/versions/0.2.0/files/mednist_gan_v0.2.0.zip
model: a pytorch module to be updated. Default to None, using the "network_def" in the bundle.
version: version name of the target bundle to download, like: "0.1.0". If `None`, will download
the latest version.
workflow: specifies the workflow type: "train" or "training" for a training workflow,
or "infer", "inference", "eval", "evaluation" for a inference workflow,
other unsupported string will raise a ValueError.
default to `train` for training workflow.
model_file: the relative path of the model weights or TorchScript module within bundle.
If `None`, "models/model.pt" or "models/model.ts" will be used.
load_ts_module: a flag to specify if loading the TorchScript module.
Expand All @@ -417,37 +427,39 @@
If used, it should be in the form of "repo_owner/repo_name/release_tag".
remove_prefix: This argument is used when `source` is "ngc". Currently, all ngc bundles
have the ``monai_`` prefix, which is not existing in their model zoo contrasts. In order to
maintain the consistency between these two sources, remove prefix is necessary.
maintain the consistency between these three sources, remove prefix is necessary.
Therefore, if specified, downloaded folder name will remove the prefix.
progress: whether to display a progress bar when downloading.
device: target device of returned weights or module, if `None`, prefer to "cuda" if existing.
key_in_ckpt: for nested checkpoint like `{"model": XXX, "optimizer": XXX, ...}`, specify the key of model
weights. if not nested checkpoint, no need to set.
config_files: extra filenames would be loaded. The argument only works when loading a TorchScript module,
see `_extra_files` in `torch.jit.load` for more details.
net_name: if not `None`, a corresponding network will be instantiated and load the achieved weights.
wyli marked this conversation as resolved.
Show resolved Hide resolved
This argument only works when loading weights.
net_kwargs: other arguments that are used to instantiate the network class defined by `net_name`.
workflow_name: specified bundle workflow name, should be a string or class, default to "ConfigWorkflow".
args_file: a JSON or YAML file to provide default values for all the args in "download" function.
copy_model_args: other arguments for the `monai.networks.copy_model_state` function.
net_override: id-value pairs to override the parameters in the network of the bundle.

Returns:
1. If `load_ts_module` is `False` and `net_name` is `None`, return model weights.
2. If `load_ts_module` is `False` and `net_name` is not `None`,
1. If `load_ts_module` is `False` and `model` is `None`,
return model weights if can't find "network_def" in the bundle,
else return an instantiated network that loaded the weights.
2. If `load_ts_module` is `False` and `model` is not `None`,
return an instantiated network that loaded the weights.
3. If `load_ts_module` is `True`, return a triple that include a TorchScript module,
the corresponding metadata dict, and extra files dict.
please check `monai.data.load_net_with_metadata` for more details.

"""
bundle_dir_ = _process_bundle_dir(bundle_dir)
copy_model_args = {} if copy_model_args is None else copy_model_args

Check warning on line 455 in monai/bundle/scripts.py

View check run for this annotation

Codecov / codecov/patch

monai/bundle/scripts.py#L455

Added line #L455 was not covered by tests

if device is None:
device = "cuda:0" if is_available() else "cpu"

Check warning on line 458 in monai/bundle/scripts.py

View check run for this annotation

Codecov / codecov/patch

monai/bundle/scripts.py#L457-L458

Added lines #L457 - L458 were not covered by tests
if model_file is None:
model_file = os.path.join("models", "model.ts" if load_ts_module is True else "model.pt")
if source == "ngc":
name = _add_ngc_prefix(name)
if remove_prefix:
name = _remove_ngc_prefix(name, prefix=remove_prefix)
full_path = os.path.join(bundle_dir_, name, model_file)
if not os.path.exists(full_path):
if not os.path.exists(full_path) or model is None:

Check warning on line 462 in monai/bundle/scripts.py

View check run for this annotation

Codecov / codecov/patch

monai/bundle/scripts.py#L462

Added line #L462 was not covered by tests
download(
name=name,
version=version,
Expand All @@ -456,10 +468,21 @@
repo=repo,
remove_prefix=remove_prefix,
progress=progress,
args_file=args_file,
)
train_config_file = bundle_dir_ / name / "configs" / f"{workflow}.json"
KumoLiu marked this conversation as resolved.
Show resolved Hide resolved
if train_config_file.is_file():
_net_override = {f"network_def#{key}": value for key, value in net_override.items()}
_workflow = create_workflow(

Check warning on line 476 in monai/bundle/scripts.py

View check run for this annotation

Codecov / codecov/patch

monai/bundle/scripts.py#L473-L476

Added lines #L473 - L476 were not covered by tests
workflow_name=workflow_name,
args_file=args_file,
config_file=str(train_config_file),
workflow=workflow,
**_net_override,
)
else:
_workflow = None

Check warning on line 484 in monai/bundle/scripts.py

View check run for this annotation

Codecov / codecov/patch

monai/bundle/scripts.py#L484

Added line #L484 was not covered by tests

if device is None:
device = "cuda:0" if is_available() else "cpu"
# loading with `torch.jit.load`
if load_ts_module is True:
return load_net_with_metadata(full_path, map_location=torch.device(device), more_extra_files=config_files)
Expand All @@ -469,13 +492,12 @@
warnings.warn(f"the state dictionary from {full_path} should be a dictionary but got {type(model_dict)}.")
model_dict = get_state_dict(model_dict)

if net_name is None:
if model is None and _workflow is None:

Check warning on line 495 in monai/bundle/scripts.py

View check run for this annotation

Codecov / codecov/patch

monai/bundle/scripts.py#L495

Added line #L495 was not covered by tests
return model_dict
net_kwargs["_target_"] = net_name
configer = ConfigComponent(config=net_kwargs)
model = configer.instantiate()
model.to(device) # type: ignore
copy_model_state(dst=model, src=model_dict if key_in_ckpt is None else model_dict[key_in_ckpt]) # type: ignore
model = _workflow.network_def if model is None else model # type: ignore
model.to(device)

Check warning on line 498 in monai/bundle/scripts.py

View check run for this annotation

Codecov / codecov/patch

monai/bundle/scripts.py#L497-L498

Added lines #L497 - L498 were not covered by tests

copy_model_state(dst=model, src=model_dict if key_in_ckpt is None else model_dict[key_in_ckpt], **copy_model_args)

Check warning on line 500 in monai/bundle/scripts.py

View check run for this annotation

Codecov / codecov/patch

monai/bundle/scripts.py#L500

Added line #L500 was not covered by tests
return model


Expand Down Expand Up @@ -675,12 +697,12 @@
final_id: ID name of the expected config expression to finalize after running, default to "finalize".
it's optional for both configs and this `run` function.
meta_file: filepath of the metadata file, if it is a list of file paths, the content of them will be merged.
Default to "configs/metadata.json", which is commonly used for bundles in MONAI model zoo.
Default to None.
config_file: filepath of the config file, if `None`, must be provided in `args_file`.
if it is a list of file paths, the content of them will be merged.
logging_file: config file for `logging` module in the program. for more details:
https://docs.python.org/3/library/logging.config.html#logging.config.fileConfig.
Default to "configs/logging.conf", which is commonly used for bundles in MONAI model zoo.
Default to None.
tracking: if not None, enable the experiment tracking at runtime with optionally configurable and extensible.
if "mlflow", will add `MLFlowHandler` to the parsed bundle with default tracking settings,
if other string, treat it as file path to load the tracking settings.
Expand Down Expand Up @@ -712,11 +734,11 @@
config_file_, meta_file_, init_id_, run_id_, final_id_, logging_file_, tracking_ = _pop_args(
_args,
config_file=None,
meta_file="configs/metadata.json",
meta_file=None,
init_id="initialize",
run_id="run",
final_id="finalize",
logging_file="configs/logging.conf",
logging_file=None,
tracking=None,
)
workflow = ConfigWorkflow(
KumoLiu marked this conversation as resolved.
Show resolved Hide resolved
Expand All @@ -734,7 +756,9 @@
workflow.finalize()


def run_workflow(workflow: str | BundleWorkflow | None = None, args_file: str | None = None, **kwargs: Any) -> None:
def run_workflow(
workflow_name: str | BundleWorkflow | None = None, args_file: str | None = None, **kwargs: Any
) -> None:
"""
Specify `bundle workflow` to run monai bundle components and workflows.
The workflow should be subclass of `BundleWorkflow` and be available to import.
Expand All @@ -748,35 +772,17 @@
python -m monai.bundle run_workflow --meta_file <meta path> --config_file <config path>

# Set the workflow to other customized BundleWorkflow subclass:
python -m monai.bundle run_workflow --workflow CustomizedWorkflow ...
python -m monai.bundle run_workflow --workflow_name CustomizedWorkflow ...

Args:
workflow: specified bundle workflow name, should be a string or class, default to "ConfigWorkflow".
workflow_name: specified bundle workflow name, should be a string or class, default to "ConfigWorkflow".
wyli marked this conversation as resolved.
Show resolved Hide resolved
args_file: a JSON or YAML file to provide default values for this API.
so that the command line inputs can be simplified.
kwargs: arguments to instantiate the workflow class.

"""

_args = _update_args(args=args_file, workflow=workflow, **kwargs)
_log_input_summary(tag="run", args=_args)
(workflow_name,) = _pop_args(_args, workflow=ConfigWorkflow) # the default workflow name is "ConfigWorkflow"
if isinstance(workflow_name, str):
workflow_class, has_built_in = optional_import("monai.bundle", name=str(workflow_name)) # search built-in
if not has_built_in:
workflow_class = locate(str(workflow_name)) # search dotted path
if workflow_class is None:
raise ValueError(f"cannot locate specified workflow class: {workflow_name}.")
elif issubclass(workflow_name, BundleWorkflow):
workflow_class = workflow_name
else:
raise ValueError(
"Argument `workflow` must be a bundle workflow class name"
f"or subclass of BundleWorkflow, got: {workflow_name}."
)

workflow_ = workflow_class(**_args)
workflow_.initialize()
workflow_ = create_workflow(workflow_name=workflow_name, args_file=args_file, **kwargs)

Check warning on line 785 in monai/bundle/scripts.py

View check run for this annotation

Codecov / codecov/patch

monai/bundle/scripts.py#L785

Added line #L785 was not covered by tests
workflow_.run()
workflow_.finalize()

Expand Down Expand Up @@ -1539,3 +1545,55 @@
copyfile(str(ckpt_file), str(models_dir / "model.pt"))
elif network is not None:
save_state(network, str(models_dir / "model.pt"))


def create_workflow(
workflow_name: str | BundleWorkflow | None = None,
config_file: str | Sequence[str] | None = None,
args_file: str | None = None,
**kwargs: Any,
) -> Any:
"""
Specify `bundle workflow` to create monai bundle workflows.
The workflow should be subclass of `BundleWorkflow` and be available to import.
It can be MONAI existing bundle workflows or user customized workflows.

Typical usage examples:

.. code-block:: python

# Specify config_file path to create workflow:
workflow = create_workflow(config_file="/workspace/spleen_ct_segmentation/configs/train.json", workflow="train")

# Set the workflow to other customized BundleWorkflow subclass to create workflow:
workflow = create_workflow(workflow_name=CustomizedWorkflow)

Args:
workflow_name: specified bundle workflow name, should be a string or class, default to "ConfigWorkflow".
config_file: filepath of the config file, if it is a list of file paths, the content of them will be merged.
args_file: a JSON or YAML file to provide default values for this API.
so that the command line inputs can be simplified.
kwargs: arguments to instantiate the workflow class.

"""
_args = _update_args(args=args_file, workflow_name=workflow_name, config_file=config_file, **kwargs)
_log_input_summary(tag="run", args=_args)
(workflow_name,) = _pop_args(_args, workflow_name=ConfigWorkflow) # the default workflow name is "ConfigWorkflow"
if isinstance(workflow_name, str):
workflow_class, has_built_in = optional_import("monai.bundle", name=str(workflow_name)) # search built-in
if not has_built_in:
workflow_class = locate(str(workflow_name)) # search dotted path
if workflow_class is None:
raise ValueError(f"cannot locate specified workflow class: {workflow_name}.")
elif issubclass(workflow_name, BundleWorkflow): # type: ignore
workflow_class = workflow_name

Check warning on line 1589 in monai/bundle/scripts.py

View check run for this annotation

Codecov / codecov/patch

monai/bundle/scripts.py#L1579-L1589

Added lines #L1579 - L1589 were not covered by tests
else:
raise ValueError(

Check warning on line 1591 in monai/bundle/scripts.py

View check run for this annotation

Codecov / codecov/patch

monai/bundle/scripts.py#L1591

Added line #L1591 was not covered by tests
"Argument `workflow` must be a bundle workflow class name"
f"or subclass of BundleWorkflow, got: {workflow_name}."
)

workflow_ = workflow_class(**_args)
workflow_.initialize()

Check warning on line 1597 in monai/bundle/scripts.py

View check run for this annotation

Codecov / codecov/patch

monai/bundle/scripts.py#L1596-L1597

Added lines #L1596 - L1597 were not covered by tests
wyli marked this conversation as resolved.
Show resolved Hide resolved

return workflow_

Check warning on line 1599 in monai/bundle/scripts.py

View check run for this annotation

Codecov / codecov/patch

monai/bundle/scripts.py#L1599

Added line #L1599 was not covered by tests
Loading