Repository: Lightning-Universe/lightning-flash

Issue:
Raise clearer error when module not available
Context:

> Hi, @jayqi - Thank you for the question. In terms of providing a more clear error, this hasn't been fixed. I'll re-open this issue, and I think a refactor will be good in Flash to add better errors if the module is not found. In case you are interested to pick this up, please feel free (also let me know so that I can assign you the issue). Else, I'll try to scope this for the next week, and create an issue and a PR around this. 🎉

cc: @ethanwharris - What do you think about the refactor to raise errors instead of running into: `NameError "T" not defined``.

Hint: https://github.com/Lightning-AI/lightning-flash/issues/1403#issuecomment-1219792770

_Originally posted by @krshrimali in https://github.com/Lightning-AI/lightning-flash/issues/1403#issuecomment-1219780935_


Discussion:
To the contributors: if anyone wants to pick it up, this is open to be taken by this weekend. If not, since this needs to be fixed - I'll attempt to pick it up and try finishing it by the next week. Feel free to let me know here if anyone is interested. 🔥 ⚡ 
hey @krshrimali, I would like to pick this up 😄 
> hey @krshrimali, I would like to pick this up 😄 

Awesome, thanks @aniketmaurya! Assigning this to you, please reach out in case you need any help. Appreciate the help! 🔥

Resolving patch:
diff --git a/flash/audio/classification/input_transform.py b/flash/audio/classification/input_transform.py
--- a/flash/audio/classification/input_transform.py
+++ b/flash/audio/classification/input_transform.py
@@ -19,7 +19,7 @@
 from flash.core.data.io.input import DataKeys
 from flash.core.data.io.input_transform import InputTransform
 from flash.core.data.transforms import ApplyToKeys
-from flash.core.utilities.imports import _TORCHAUDIO_AVAILABLE, _TORCHVISION_AVAILABLE
+from flash.core.utilities.imports import _TORCHAUDIO_AVAILABLE, _TORCHVISION_AVAILABLE, requires
 
 if _TORCHVISION_AVAILABLE:
     from torchvision import transforms as T
@@ -51,6 +51,7 @@ def train_per_sample_transform(self) -> Callable:
             ]
         )
 
+    @requires("audio")
     def per_sample_transform(self) -> Callable:
         return T.Compose(
             [
diff --git a/flash/core/utilities/imports.py b/flash/core/utilities/imports.py
--- a/flash/core/utilities/imports.py
+++ b/flash/core/utilities/imports.py
@@ -162,7 +162,7 @@ class Image:
 )
 _SERVE_AVAILABLE = _FASTAPI_AVAILABLE and _PYDANTIC_AVAILABLE and _CYTOOLZ_AVAILABLE and _UVICORN_AVAILABLE
 _POINTCLOUD_AVAILABLE = _OPEN3D_AVAILABLE and _TORCHVISION_AVAILABLE
-_AUDIO_AVAILABLE = all([_TORCHAUDIO_AVAILABLE, _LIBROSA_AVAILABLE, _TRANSFORMERS_AVAILABLE])
+_AUDIO_AVAILABLE = all([_TORCHAUDIO_AVAILABLE, _TORCHVISION_AVAILABLE, _LIBROSA_AVAILABLE, _TRANSFORMERS_AVAILABLE])
 _GRAPH_AVAILABLE = (
     _TORCH_SCATTER_AVAILABLE and _TORCH_SPARSE_AVAILABLE and _TORCH_GEOMETRIC_AVAILABLE and _NETWORKX_AVAILABLE
 )
diff --git a/flash/image/segmentation/input_transform.py b/flash/image/segmentation/input_transform.py
--- a/flash/image/segmentation/input_transform.py
+++ b/flash/image/segmentation/input_transform.py
@@ -17,7 +17,7 @@
 from flash.core.data.io.input import DataKeys
 from flash.core.data.io.input_transform import InputTransform
 from flash.core.data.transforms import ApplyToKeys, kornia_collate, KorniaParallelTransforms
-from flash.core.utilities.imports import _KORNIA_AVAILABLE, _TORCHVISION_AVAILABLE
+from flash.core.utilities.imports import _KORNIA_AVAILABLE, _TORCHVISION_AVAILABLE, requires
 
 if _KORNIA_AVAILABLE:
     import kornia as K
@@ -47,6 +47,7 @@ class SemanticSegmentationInputTransform(InputTransform):
     mean: Union[float, Tuple[float, float, float]] = (0.485, 0.456, 0.406)
     std: Union[float, Tuple[float, float, float]] = (0.229, 0.224, 0.225)
 
+    @requires("image")
     def train_per_sample_transform(self) -> Callable:
         return T.Compose(
             [
@@ -61,6 +62,7 @@ def train_per_sample_transform(self) -> Callable:
             ]
         )
 
+    @requires("image")
     def per_sample_transform(self) -> Callable:
         return T.Compose(
             [
@@ -72,6 +74,7 @@ def per_sample_transform(self) -> Callable:
             ]
         )
 
+    @requires("image")
     def predict_per_sample_transform(self) -> Callable:
         return ApplyToKeys(
             DataKeys.INPUT,


Test patch: