Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
10 changes: 9 additions & 1 deletion monai/handlers/tensorboard_handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
Engine, _ = optional_import(
"ignite.engine", IgniteInfo.OPT_IMPORT_VERSION, min_version, "Engine", as_type="decorator"
)
SummaryWriter, _ = optional_import("torch.utils.tensorboard", name="SummaryWriter")
SummaryWriter, _tb_available = optional_import("torch.utils.tensorboard", name="SummaryWriter")
SummaryWriterX, _ = optional_import("tensorboardX", name="SummaryWriter")

DEFAULT_TAG = "Loss"
Expand All @@ -46,10 +46,18 @@ class TensorBoardHandler:
default to create a new TensorBoard writer.
log_dir: if using default SummaryWriter, write logs to this directory, default is `./runs`.

Raises:
RuntimeError: When ``summary_writer`` is ``None`` and the ``tensorboard`` package is not installed.

"""

def __init__(self, summary_writer: SummaryWriter | SummaryWriterX | None = None, log_dir: str = "./runs"):
if summary_writer is None:
if not _tb_available:
raise RuntimeError(
"TensorBoardHandler requires tensorboard to be installed. "
"Please install it with: pip install tensorboard"
)
self._writer = SummaryWriter(log_dir=log_dir)
self.internal_writer = True
else:
Expand Down
11 changes: 10 additions & 1 deletion tests/handlers/test_handler_tb_stats.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@
import glob
import tempfile
import unittest
from unittest.mock import MagicMock
from unittest.mock import MagicMock, patch

from ignite.engine import Engine, Events
from parameterized import parameterized

from monai.handlers import TensorBoardStatsHandler
from monai.handlers.tensorboard_handlers import TensorBoardHandler
from monai.utils import optional_import

SummaryWriter, has_tb = optional_import("torch.utils.tensorboard", name="SummaryWriter")
Expand Down Expand Up @@ -162,5 +163,13 @@ def _update_metric(engine):
) # 2 = len([1, 3]) from event_filter


class TestTensorBoardHandlerMissingDependency(unittest.TestCase):

def test_raises_when_tensorboard_unavailable(self):
Comment on lines +166 to +168

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Add docstrings to the new test definitions.

Document the test class and method, for example: TestTensorBoardHandlerMissingDependency verifies missing TensorBoard handling, and test_raises_when_tensorboard_unavailable verifies the raised exception.

As per path instructions, “Docstrings should be present for all definition[s] which describe each variable, return value, and raised exception in the appropriate section of the Google-style of docstrings.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/handlers/test_handler_tb_stats.py` around lines 166 - 168, Add
Google-style docstrings to the new TestTensorBoardHandlerMissingDependency class
and its test_raises_when_tensorboard_unavailable method, describing the missing
TensorBoard handling and the exception the test verifies; include appropriate
sections for the raised exception where applicable.

Source: Path instructions

with patch("monai.handlers.tensorboard_handlers._tb_available", False):
with self.assertRaises(RuntimeError):
TensorBoardHandler()
Comment on lines +169 to +171

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Assert the installation guidance, not only the exception type.

The PR objective requires an actionable pip install tensorboard message; the current test would pass even if that guidance were removed.

Suggested assertion
-            with self.assertRaises(RuntimeError):
+            with self.assertRaisesRegex(RuntimeError, r"pip install tensorboard"):
                 TensorBoardHandler()
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
with patch("monai.handlers.tensorboard_handlers._tb_available", False):
with self.assertRaises(RuntimeError):
TensorBoardHandler()
with patch("monai.handlers.tensorboard_handlers._tb_available", False):
with self.assertRaisesRegex(RuntimeError, r"pip install tensorboard"):
TensorBoardHandler()
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/handlers/test_handler_tb_stats.py` around lines 169 - 171, Update the
TensorBoardHandler test to inspect the raised RuntimeError message, asserting it
includes actionable installation guidance for installing TensorBoard via “pip
install tensorboard,” while retaining the existing _tb_available=False setup and
exception-type assertion.



if __name__ == "__main__":
unittest.main()
Loading