Skip to content

Commit 60e1854

Browse files
committed
Make the contructor of the derived operators explictly requiring fragment as arg.
Signed-off-by: M Q <mingmelvinq@nvidia.com>
1 parent c1395ee commit 60e1854

File tree

5 files changed

+44
-31
lines changed

5 files changed

+44
-31
lines changed
Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,5 @@
1-
from pathlib import Path
2-
31
from app import App
42

53
if __name__ == "__main__":
6-
app = App()
7-
8-
# If there exists the named config file, use it to configure the objects which support it.
9-
config_file = Path(__file__).parent.absolute() / "simple_imaing_app.yaml"
10-
if config_file.exists():
11-
app.config(config_file)
4+
App().run()
125

13-
app.run()

examples/apps/simple_imaging_app/app.py

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ def compose(self):
4747
output_data_path = Path(app_context.output_path)
4848
print(f"sample_data_path: {sample_data_path}")
4949

50+
# Please note that the Application object, self, is passed as the first positonal argument
51+
# and the others as kwargs.
52+
# Also note the CountCondition of 1 on the first operator, indicating to the application executor
53+
# to invoke this operator, hence the pipleline, only once.
5054
sobel_op = SobelOperator(self, CountCondition(self, 1), input_folder=sample_data_path, name="sobel_op")
5155
median_op = MedianOperator(self, name="median_op")
5256
gaussian_op = GaussianOperator(self, output_folder=output_data_path, name="gaussian_op")
@@ -56,7 +60,7 @@ def compose(self):
5660
{
5761
("out1", "in1"),
5862
},
59-
) # Using port name is optional for single port cases
63+
)
6064
self.add_flow(
6165
median_op,
6266
gaussian_op,
@@ -66,16 +70,9 @@ def compose(self):
6670
"in1",
6771
)
6872
},
69-
)
73+
) # Using port name is optional for single port cases
7074

7175

7276
if __name__ == "__main__":
7377
load_env_log_level()
74-
app = App()
75-
76-
# If there exists the named config file, use it to configure the objects which support it.
77-
config_file = Path(__file__).parent.absolute() / "simple_imaing_app.yaml"
78-
if config_file.exists():
79-
app.config(config_file)
80-
81-
app.run()
78+
App().run()

examples/apps/simple_imaging_app/gaussian_operator.py

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
from skimage.filters import gaussian
1515
from skimage.io import imsave
1616

17-
from monai.deploy.core import ConditionType, Operator, OperatorSpec
17+
from monai.deploy.core import ConditionType, Fragment, Operator, OperatorSpec
1818

1919

2020
# If `pip_packages` is specified, the definition will be aggregated with the package dependency list of other
@@ -23,12 +23,24 @@
2323
class GaussianOperator(Operator):
2424
"""This Operator implements a smoothening based on Gaussian.
2525
26-
It ingests a single input, an array, but emits none, instead it saves a file in the output folder.
26+
It has the following input and output:
27+
single input:
28+
an image array object
29+
single output:
30+
an image arrary object, without enforcing a downsteam receiver
31+
32+
Besides, this operator also saves the image file in the given output folder.
2733
"""
2834

2935
DEFAULT_OUTPUT_FOLDER = Path.cwd() / "output"
3036

31-
def __init__(self, *args, output_folder: Path, **kwargs):
37+
def __init__(self, fragment: Fragment, *args, output_folder: Path, **kwargs):
38+
"""Create an instance to be part of the given application (fragment).
39+
40+
Args:
41+
fragment (Fragment): The instance of Application class which is derived from Fragment
42+
output_folder (Path): The folder to save the output file.
43+
"""
3244
self.output_folder = output_folder if output_folder else GaussianOperator.DEFAULT_OUTPUT_FOLDER
3345
self.index = 0
3446

@@ -40,11 +52,11 @@ def __init__(self, *args, output_folder: Path, **kwargs):
4052
self.channel_axis = 2
4153

4254
# Need to call the base class constructor last
43-
super().__init__(*args, **kwargs)
55+
super().__init__(fragment, *args, **kwargs)
4456

4557
def setup(self, spec: OperatorSpec):
4658
spec.input("in1")
47-
spec.output("out1").condition(ConditionType.NONE) # This condition type allows for no or not-ready receiver.
59+
spec.output("out1").condition(ConditionType.NONE) # Condition is for no or not-ready receiver ports.
4860
spec.param("sigma_default", 0.2)
4961
spec.param("channel_axis", 2)
5062

examples/apps/simple_imaging_app/median_operator.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
from skimage.filters import median
1313

14-
from monai.deploy.core import Operator, OperatorSpec
14+
from monai.deploy.core import Fragment, Operator, OperatorSpec
1515

1616

1717
# If `pip_packages` is specified, the definition will be aggregated with the package dependency list of other
@@ -21,15 +21,21 @@ class MedianOperator(Operator):
2121
"""This Operator implements a noise reduction.
2222
2323
The algorithm is based on the median operator.
24-
It ingests a single input and provides a single output, both are of type in-memory array
24+
It ingests a single input and provides a single output, both are in-memory image arrays
2525
"""
2626

2727
# Define __init__ method with super().__init__() if you want to override the default behavior.
28-
def __init__(self, *args, **kwargs):
28+
def __init__(self, fragment: Fragment, *args, **kwargs):
29+
"""Create an instance to be part of the given application (fragment).
30+
31+
Args:
32+
fragment (Fragment): The instance of Application class which is derived from Fragment
33+
"""
34+
2935
self.index = 0
3036

3137
# Need to call the base class constructor last
32-
super().__init__(*args, **kwargs)
38+
super().__init__(fragment, *args, **kwargs)
3339

3440
def setup(self, spec: OperatorSpec):
3541
spec.input("in1")

examples/apps/simple_imaging_app/sobel_operator.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
from pathlib import Path
1313

14-
from monai.deploy.core import Operator, OperatorSpec
14+
from monai.deploy.core import Fragment, Operator, OperatorSpec
1515

1616

1717
# # If `pip_packages` is specified, the definition will be aggregated with the package dependency list of other
@@ -29,7 +29,13 @@ class SobelOperator(Operator):
2929

3030
DEFAULT_INPUT_FOLDER = Path.cwd() / "input"
3131

32-
def __init__(self, *args, input_folder: Path, **kwargs):
32+
def __init__(self, fragment: Fragment, *args, input_folder: Path, **kwargs):
33+
"""Create an instance to be part of the given application (fragment).
34+
35+
Args:
36+
fragment (Fragment): An instance of the Application class which is derived from Fragment
37+
input_folder (Path): The folder to read the image file from
38+
"""
3339
self.index = 0
3440

3541
# May want to validate the path, but it should really be validated when the compute function is called, also,
@@ -39,7 +45,7 @@ def __init__(self, *args, input_folder: Path, **kwargs):
3945
)
4046

4147
# Need to call the base class constructor last
42-
super().__init__(*args, **kwargs)
48+
super().__init__(fragment, *args, **kwargs)
4349

4450
def setup(self, spec: OperatorSpec):
4551
spec.output("out1")

0 commit comments

Comments
 (0)