Creating Operator classes

Operator Class

Each Operator class inherits Operator class.

An Operator class definition example
 1from pathlib import Path
 2from monai.deploy.core import (ExecutionContext, Image, InputContext,
 3                               Operator, OutputContext, OperatorSpec)
 4
 5
 6class MyOperator(Operator):
 7    """Sample Operator implementation."""
 8
 9    def setup(self, spec: OperatorSpec):
10        spec.input("image_path")
11        spec.output("image")
12        spec.output("metadata")
13
14    def compute(self, op_input: InputContext, op_output: OutputContext, context: ExecutionContext):
15        from skimage import filters, io
16
17        # Get input image
18        image_path = Path(op_input.receive("image_path"))  # omitting validation for brevity
19        if image_path.is_dir():
20            image_path = next(image_path.glob("*.*"))  # take the first file
21        input_image = io.imread(image_path)
22
23        # Get mask image
24        mask = op_input.get("mask").asnumpy()
25
26        # Apply filter
27        output_image = filters.sobel(input_image, mask)
28
29        # Prepare output metadata
30        metadata = {"shape": input_image.shape, "dtype": input_image.dtype}
31
32        # Set output
33        op_output.emit(Image(output_image), "image")
34        op_output.emit(metadata, "metadata")

setup() method

In prior releases, the input and output properties of the operator are specified by using @input and @output decorators, but starting with release v0.6, the setup() method is used.

compute() method

compute() method in Operator class is an abstract method that needs to be implemented by the Operator developer.

Please check the description of compute() method to find a way to access

  1. Operator’s input/output

  2. Application’s input/output

  3. Model’s name/path/predictor

Note that, if the operator is a leaf operator in the workflow graph and the operator output is file(s) written to the file system, the path needs to be set using the operator’s constructor or a named input for path object or string. The leaf operator can also have in-memory output(s) without requiring other operator(s) as receiver, if the output is configured correctly like in the GaussionOperator in Simple Image Processing App

Package dependencies

The dependencies of the operator need to be captured in a “requirements.txt”, instead of using the @env decorator as in earlier releases. The aggregated requirement definitions for an application are then store in a consolidated “requirements.txt” file, to be installed at packaging time.

Creating a Reusable Operator

You can create a common Operator class so that other Operator classes can just inherit the common Operator and implement only part of the compute() method to handle specific cases.

Please refer to the following examples: