Skip to content

Commit 07013c0

Browse files
authored
Merge branch 'Project-MONAI:main' into main
2 parents f8abbf7 + 57b0e9d commit 07013c0

25 files changed

+96
-66
lines changed

.github/ISSUE_TEMPLATE/enhancement_request.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ assignees: ''
77

88
---
99

10-
**Is your enhancemnet request related to a problem? Please describe.**
10+
**Is your enhancement request related to a problem? Please describe.**
1111
<!--
1212
A clear and concise description of what the enhancement needs to be. Ex. The example app can be improved to show me how to [...]
1313
-->

examples/apps/ai_livertumor_seg_app/livertumor_seg_operator.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,14 +52,12 @@ class LiverTumorSegOperator(Operator):
5252
"""
5353

5454
def __init__(self):
55-
5655
self.logger = logging.getLogger("{}.{}".format(__name__, type(self).__name__))
5756
super().__init__()
5857
self._input_dataset_key = "image"
5958
self._pred_dataset_key = "pred"
6059

6160
def compute(self, op_input: InputContext, op_output: OutputContext, context: ExecutionContext):
62-
6361
input_image = op_input.get("image")
6462
if not input_image:
6563
raise ValueError("Input image is not found.")

examples/apps/ai_unetr_seg_app/unetr_seg_operator.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,12 @@ class UnetrSegOperator(Operator):
4646
"""
4747

4848
def __init__(self):
49-
5049
self.logger = logging.getLogger("{}.{}".format(__name__, type(self).__name__))
5150
super().__init__()
5251
self._input_dataset_key = "image"
5352
self._pred_dataset_key = "pred"
5453

5554
def compute(self, op_input: InputContext, op_output: OutputContext, context: ExecutionContext):
56-
5755
input_image = op_input.get("image")
5856
if not input_image:
5957
raise ValueError("Input image is not found.")

monai/deploy/core/application.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ def __init__(
8282
self.description = get_docstring(self.__class__)
8383
if not self.version:
8484
try:
85-
from _version import get_versions
85+
from monai.deploy._version import get_versions
8686

8787
self.version = get_versions()["version"]
8888
except ImportError:

monai/deploy/core/executors/single_process_executor.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ def run(self):
141141
)
142142

143143
next_op_exec_context = ExecutionContext(exec_context, next_op)
144-
for (out_label, in_labels) in io_map.items():
144+
for out_label, in_labels in io_map.items():
145145
output = op_exec_context.output_context.get(out_label)
146146
for in_label in in_labels:
147147
next_op_exec_context.input_context.set(output, in_label)

monai/deploy/core/graphs/nx_digraph.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,5 +52,5 @@ def gen_worklist(self) -> Generator[Optional[Operator], None, None]:
5252
return worklist
5353

5454
def gen_next_operators(self, op: Operator) -> Generator[Optional[Operator], None, None]:
55-
for (_, v) in self._graph.out_edges(op):
55+
for _, v in self._graph.out_edges(op):
5656
yield v

monai/deploy/operators/dicom_data_loader_operator.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,6 @@ def _load_data(self, files: List[str]):
118118
logging.warning(f"Ignored {file}, reason being: {ex}")
119119

120120
for sop_instance in sop_instances:
121-
122121
study_instance_uid = sop_instance[0x0020, 0x000D].value.name # name is the UID as str
123122

124123
if study_instance_uid not in study_dict:

monai/deploy/operators/dicom_encapsulated_pdf_writer_operator.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@
4242
@md.output("dicom_instance", DataPath, IOType.DISK)
4343
@md.env(pip_packages=["pydicom >= 1.4.2", "PyPDF2 >= 2.11.1", "monai"])
4444
class DICOMEncapsulatedPDFWriterOperator(Operator):
45-
4645
DCM_EXTENSION = ".dcm"
4746

4847
def __init__(

monai/deploy/operators/dicom_seg_writer_operator.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
import datetime
1313
import logging
14+
import os
1415
from pathlib import Path
1516
from random import randint
1617
from typing import TYPE_CHECKING, Dict, List, Optional, Sequence, Union

monai/deploy/operators/dicom_series_to_volume_operator.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,6 @@ def _get_instance_properties(obj: object, not_none: bool = True) -> Dict:
389389

390390

391391
def test():
392-
393392
from pathlib import Path
394393

395394
from monai.deploy.operators.dicom_data_loader_operator import DICOMDataLoaderOperator

monai/deploy/operators/dicom_text_sr_writer_operator.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@
3939
@md.output("dicom_instance", DataPath, IOType.DISK)
4040
@md.env(pip_packages=["pydicom >= 1.4.2", "monai"])
4141
class DICOMTextSRWriterOperator(Operator):
42-
4342
# File extension for the generated DICOM Part 10 file.
4443
DCM_EXTENSION = ".dcm"
4544

monai/deploy/operators/dicom_utils.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@ class ModelInfo(object):
6060
"""
6161

6262
def __init__(self, creator: str = "", name: str = "", version: str = "", uid: str = ""):
63-
6463
self.creator = creator if isinstance(creator, str) else ""
6564
self.name = name if isinstance(name, str) else ""
6665
self.version = version if isinstance(version, str) else ""
@@ -77,7 +76,6 @@ def __init__(
7776
series_number: str = "0000",
7877
software_version_number: str = "",
7978
):
80-
8179
self.manufacturer = manufacturer if isinstance(manufacturer, str) else ""
8280
self.manufacturer_model = manufacturer_model if isinstance(manufacturer_model, str) else ""
8381
self.series_number = series_number if isinstance(series_number, str) else ""

monai/deploy/operators/monai_bundle_inference_operator.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,8 @@ def _read_from_archive(archive, root_name: str, config_name: str, do_search=True
7878

7979
# Try directly read with constructed and expected path into the archive
8080
for suffix in bundle_suffixes:
81+
path = Path(root_name, config_folder, config_name).with_suffix(suffix)
8182
try:
82-
path = Path(root_name, config_folder, config_name).with_suffix(suffix)
8383
logging.debug(f"Trying to read config '{config_name}' content from {path}.")
8484
content_text = archive.read(str(path))
8585
break
@@ -268,6 +268,7 @@ def _ensure_str_list(config_names):
268268

269269
DEFAULT_BundleConfigNames = BundleConfigNames()
270270

271+
271272
# The operator env decorator defines the required pip packages commonly used in the Bundles.
272273
# The MONAI Deploy App SDK packager currently relies on the App to consolidate all required packages in order to
273274
# install them in the MAP Docker image.
@@ -768,7 +769,6 @@ def _convert_from_image(self, img: Image) -> Tuple[np.ndarray, Dict]:
768769
or ("spacing" in img_meta_dict and "original_affine" in img_meta_dict)
769770
or "row_pixel_spacing" not in img_meta_dict
770771
):
771-
772772
return img.asnumpy(), img_meta_dict
773773
else:
774774
return self._convert_from_image_dicom_source(img)

monai/deploy/utils/importutil.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ def exact_version(the_module, version_str: str = "") -> bool:
155155
Returns True if the module's __version__ matches version_str
156156
"""
157157
if not hasattr(the_module, "__version__"):
158-
warnings.warn(f"{the_module} has no attribute __version__ in exact_version check.")
158+
warnings.warn(f"{the_module} has no attribute __version__ in exact_version check.", stacklevel=2)
159159
return False
160160
return bool(the_module.__version__ == version_str)
161161

notebooks/tutorials/02_mednist_app-prebuilt.ipynb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@
8484
"Collecting networkx>=2.4\n",
8585
" Downloading networkx-2.5.1-py3-none-any.whl (1.6 MB)\n",
8686
"\u001b[K |████████████████████████████████| 1.6 MB 12.8 MB/s eta 0:00:01\n",
87-
"\u001b[?25hCollecting typeguard>=2.12.1\n",
87+
"\u001b[?25hCollecting typeguard~=2.12.1\n",
8888
" Downloading typeguard-2.12.1-py3-none-any.whl (17 kB)\n",
8989
"Collecting numpy>=1.17\n",
9090
" Downloading numpy-1.19.5-cp36-cp36m-manylinux2010_x86_64.whl (14.8 MB)\n",

notebooks/tutorials/03_segmentation_app.ipynb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@
104104
"!python -c \"import pydicom\" || pip install -q \"pydicom>=1.4.2\"\n",
105105
"!python -c \"import highdicom\" || pip install -q \"highdicom>=0.18.2\"\n",
106106
"!python -c \"import SimpleITK\" || pip install -q \"SimpleITK>=2.0.0\"\n",
107-
"!python -c \"import typeguard\" || pip install -q \"typeguard>=2.12.1\"\n",
107+
"!python -c \"import typeguard\" || pip install -q \"typeguard~=2.12.1\"\n",
108108
"\n",
109109
"# Install MONAI Deploy App SDK package\n",
110110
"!python -c \"import monai.deploy\" || pip install --upgrade -q \"monai-deploy-app-sdk\""

notebooks/tutorials/03_segmentation_viz_app.ipynb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@
113113
"!python -c \"import pydicom\" || pip install -q \"pydicom>=1.4.2\"\n",
114114
"!python -c \"import highdicom\" || pip install -q \"highdicom>=0.18.2\"\n",
115115
"!python -c \"import SimpleITK\" || pip install -q \"SimpleITK>=2.0.0\"\n",
116-
"!python -c \"import typeguard\" || pip install -q \"typeguard>=2.12.1\"\n",
116+
"!python -c \"import typeguard\" || pip install -q \"typeguard~=2.12.1\"\n",
117117
"\n",
118118
"# Install MONAI Deploy App SDK package\n",
119119
"!python -c \"import monai.deploy\" || pip install --upgrade -q \"monai-deploy-app-sdk\"\n",

notebooks/tutorials/06_monai_bundle_app.ipynb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@
106106
"!python -c \"import pydicom\" || pip install -q \"pydicom>=1.4.2\"\n",
107107
"!python -c \"import highdicom\" || pip install -q \"highdicom>=0.18.2\"\n",
108108
"!python -c \"import SimpleITK\" || pip install -q \"SimpleITK>=2.0.0\"\n",
109-
"!python -c \"import typeguard\" || pip install -q \"typeguard>=2.12.1\"\n",
109+
"!python -c \"import typeguard\" || pip install -q \"typeguard~=2.12.1\"\n",
110110
"\n",
111111
"# Install MONAI Deploy App SDK package\n",
112112
"!python -c \"import monai.deploy\" || pip install --upgrade -q \"monai-deploy-app-sdk\""

notebooks/tutorials/07_multi_model_app.ipynb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@
144144
"!python -c \"import pydicom\" || pip install -q \"pydicom>=1.4.2\"\n",
145145
"!python -c \"import highdicom\" || pip install -q \"highdicom>=0.18.2\"\n",
146146
"!python -c \"import SimpleITK\" || pip install -q \"SimpleITK>=2.0.0\"\n",
147-
"!python -c \"import typeguard\" || pip install -q \"typeguard>=2.12.1\"\n",
147+
"!python -c \"import typeguard\" || pip install -q \"typeguard~=2.12.1\"\n",
148148
"\n",
149149
"# Install MONAI Deploy App SDK package\n",
150150
"!python -c \"import monai.deploy\" || pip install --upgrade -q \"monai-deploy-app-sdk\""

platforms/nuance_pin/app/inference.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,6 @@ def detection_list(self):
8282
@md.env(pip_packages=["monai>=0.8.1", "torch>=1.5", "numpy>=1.21", "nibabel"])
8383
class LungNoduleInferenceOperator(Operator):
8484
def __init__(self, model_path: str = "model/model.ts"):
85-
8685
self.logger = logging.getLogger("{}.{}".format(__name__, type(self).__name__))
8786
super().__init__()
8887
self._input_dataset_key = "image"
@@ -125,7 +124,6 @@ def __init__(self, model_path: str = "model/model.ts"):
125124
self.detector.eval()
126125

127126
def compute(self, op_input: InputContext, op_output: OutputContext, context: ExecutionContext):
128-
129127
input_image = op_input.get("image")
130128
if not input_image:
131129
raise ValueError("Input image not found.")

platforms/nuance_pin/app/post_inference_ops.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ def __init__(self, pin_processor: Optional[AiJobProcessor], *args, **kwargs):
3636
self.pin_processor = pin_processor
3737

3838
def compute(self, op_input: InputContext, op_output: OutputContext, context: ExecutionContext):
39-
4039
selected_study = op_input.get("original_dicom")[0] # assuming a single study
4140
selected_series = selected_study.selected_series[0] # assuming a single series
4241
detection_result: DetectionResult = op_input.get("detection_predictions").detection_list[0]
@@ -60,7 +59,6 @@ def compute(self, op_input: InputContext, op_output: OutputContext, context: Exe
6059
accession = all_ref_images[0].AccessionNumber
6160

6261
for inst_num, (box_data, box_score) in enumerate(zip(detection_result.box_data, detection_result.score_data)):
63-
6462
tracking_id = f"{accession}_nodule_{inst_num}" # site-specific ID
6563
tracking_uid = hd.UID()
6664

@@ -160,7 +158,6 @@ def __init__(self, pin_processor: Optional[AiJobProcessor], *args, **kwargs):
160158
self.pin_processor = pin_processor
161159

162160
def compute(self, op_input: InputContext, op_output: OutputContext, context: ExecutionContext):
163-
164161
selected_study = op_input.get("original_dicom")[0] # assuming a single study
165162
selected_series = selected_study.selected_series[0] # assuming a single series
166163
detection_result: DetectionResult = op_input.get("detection_predictions").detection_list[0]
@@ -190,7 +187,6 @@ def compute(self, op_input: InputContext, op_output: OutputContext, context: Exe
190187
slice_coords = list(range(len(selected_series.series.get_sop_instances())))
191188

192189
for box_data, box_score in zip(detection_result.box_data, detection_result.score_data):
193-
194190
affected_slice_idx = [
195191
idx
196192
for idx, slice_coord in enumerate(slice_coords)

platforms/nuance_pin/app_wrapper.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@
5050

5151

5252
class MONAIAppWrapper(AiJobProcessor):
53-
5453
partner_name = os.environ["AI_PARTNER_NAME"]
5554
service_name = os.environ["AI_SVC_NAME"]
5655
service_version = os.environ["AI_SVC_VERSION"]

pyproject.toml

Lines changed: 74 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,5 +36,78 @@ exclude = '''
3636
'''
3737

3838
# https://github.com/microsoft/pyright/blob/main/docs/configuration.md
39+
# NOTE: All relative paths are relative to the location of this file.
3940
[tool.pyright]
40-
ignore = ["versioneer.py", "_version.py"]
41+
ignore = ["versioneer.py", "_version.py"]
42+
43+
# https://google.github.io/pytype/
44+
[tool.pytype]
45+
# Space-separated list of files or directories to exclude.
46+
exclude = [
47+
'versioneer.py',
48+
'_version.py',
49+
'**/_version.py',
50+
]
51+
# Space-separated list of files or directories to process.
52+
inputs = [
53+
'monai',
54+
]
55+
# Keep going past errors to analyze as many files as possible.
56+
keep_going = true
57+
# Run N jobs in parallel. When 'auto' is used, this will be equivalent to the
58+
# number of CPUs on the host system.
59+
jobs = 8
60+
# All pytype output goes here.
61+
output = '.pytype'
62+
# Platform (e.g., "linux", "win32") that the target code runs on.
63+
platform = 'linux'
64+
# Paths to source code directories, separated by ':'.
65+
pythonpath = '.'
66+
67+
# Always use function return type annotations. This flag is temporary and will
68+
# be removed once this behavior is enabled by default.
69+
always_use_return_annotations = false
70+
71+
# Enable parameter count checks for overriding methods. This flag is temporary
72+
# and will be removed once this behavior is enabled by default.
73+
overriding_parameter_count_checks = false
74+
75+
# Enable return type checks for overriding methods. This flag is temporary and
76+
# will be removed once this behavior is enabled by default.
77+
overriding_return_type_checks = true
78+
79+
# Use the enum overlay for more precise enum checking. This flag is temporary
80+
# and will be removed once this behavior is enabled by default.
81+
use_enum_overlay = false
82+
83+
# Opt-in: Do not allow Any as a return type.
84+
no_return_any = false
85+
86+
# Experimental: Support pyglib's @cached.property.
87+
enable_cached_property = false
88+
89+
# Experimental: Infer precise return types even for invalid function calls.
90+
precise_return = false
91+
92+
# Experimental: Solve unknown types to label with structural types.
93+
protocols = false
94+
95+
# Experimental: Only load submodules that are explicitly imported.
96+
strict_import = false
97+
98+
# Experimental: Enable exhaustive checking of function parameter types.
99+
strict_parameter_checks = false
100+
101+
# Experimental: Emit errors for comparisons between incompatible primitive
102+
# types.
103+
strict_primitive_comparisons = false
104+
105+
# Space-separated list of error names to ignore.
106+
disable = [
107+
'pyi-error',
108+
'container-type-mismatch',
109+
'attribute-error',
110+
]
111+
112+
# Don't report errors.
113+
report_errors = true

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
numpy>=1.21.6
22
networkx>=2.4
33
colorama>=0.4.1
4-
typeguard>=2.12.1
4+
typeguard~=2.12.1

0 commit comments

Comments
 (0)