Repository: Project-MONAI/MONAI

Issue:
Add docs for apps folder
**Is your feature request related to a problem? Please describe.**
Need to add docs for apps as we already have several interesting APIs.


Discussion:
Nic-Ma: /black

Patch:
diff --git a/docs/source/apps.rst b/docs/source/apps.rst
new file mode 100644
index 00000000..8b025983
--- /dev/null
+++ b/docs/source/apps.rst
@@ -0,0 +1,27 @@
+:github_url: https://github.com/Project-MONAI/MONAI
+
+.. _apps:
+
+Applications
+============
+.. currentmodule:: monai.apps
+
+`Datasets`
+----------
+
+.. autoclass:: MedNISTDataset
+    :members:
+
+.. autoclass:: DecathlonDataset
+    :members:
+
+`Utilities`
+-----------
+
+.. autofunction:: check_md5
+
+.. autofunction:: download_url
+
+.. autofunction:: extractall
+
+.. autofunction:: download_and_extract
diff --git a/docs/source/index.rst b/docs/source/index.rst
index 1f766b85..122a6ab5 100644
--- a/docs/source/index.rst
+++ b/docs/source/index.rst
@@ -49,6 +49,7 @@ Technical documentation is available at `docs.monai.io <https://docs.monai.io>`_
    :maxdepth: 1
    :caption: APIs
 
+   apps
    transforms
    losses
    networks
diff --git a/monai/apps/datasets.py b/monai/apps/datasets.py
index 17b80a50..c6d33bf2 100644
--- a/monai/apps/datasets.py
+++ b/monai/apps/datasets.py
@@ -28,8 +28,9 @@ class MedNISTDataset(Randomizable, CacheDataset):
     Args:
         root_dir: target directory to download and load MedNIST dataset.
         section: expected data section, can be: `training`, `validation` or `test`.
-        transform: transforms to execute operations on input data. the default transform is composed by
-            `LoadPNGd` and `AddChanneld`, which can load data into numpy array with [C, H, W] shape.
+        transform: transforms to execute operations on input data. the default transform is `LoadPNGd`,
+            which can load data into numpy array with [H, W] shape. for further usage, use `AddChanneld`
+            to convert the shape to [C, H, W, D].
         download: whether to download and extract the MedNIST from resource link, default is False.
             if expected file already exists, skip downloading even set it to True.
             user can manually copy `MedNIST.tar.gz` file or `MedNIST` folder to root directory.
@@ -58,7 +59,7 @@ class MedNISTDataset(Randomizable, CacheDataset):
         self,
         root_dir: str,
         section: str,
-        transform: Callable[..., Any] = Compose([LoadPNGd("image"), AddChanneld("image")]),
+        transform: Callable[..., Any] = LoadPNGd("image"),
         download: bool = False,
         seed: int = 0,
         val_frac: float = 0.1,
@@ -137,8 +138,9 @@ class DecathlonDataset(Randomizable, CacheDataset):
             "Task03_Liver", "Task04_Hippocampus", "Task05_Prostate", "Task06_Lung", "Task07_Pancreas",
             "Task08_HepaticVessel", "Task09_Spleen", "Task10_Colon").
         section: expected data section, can be: `training`, `validation` or `test`.
-        transform: transforms to execute operations on input data. the default transform is composed by
-            `LoadNiftid` and `AddChanneld`, which can load data into numpy array with [C, H, W, D] shape.
+        transform: transforms to execute operations on input data. the default transform is `LoadNiftid`,
+            which can load Nifit format data into numpy array with [H, W, D] or [H, W, D, C] shape.
+            for further usage, use `AddChanneld` or `AsChannelFirstd` to convert the shape to [C, H, W, D].
         download: whether to download and extract the Decathlon from resource link, default is False.
             if expected file already exists, skip downloading even set it to True.
             user can manually copy tar file or dataset folder to the root directory.
@@ -154,6 +156,7 @@ class DecathlonDataset(Randomizable, CacheDataset):
             if 0 a single thread will be used. Default is 0.
 
     Example::
+
         transform = Compose(
             [
                 LoadNiftid(keys=["image", "label"]),
@@ -162,9 +165,11 @@ class DecathlonDataset(Randomizable, CacheDataset):
                 ToTensord(keys=["image", "label"]),
             ]
         )
+
         data = DecathlonDataset(
             root_dir="./", task="Task09_Spleen", transform=transform, section="validation", download=True
         )
+
         print(data[0]["image"], data[0]["label"])
 
     Raises:
@@ -204,7 +209,7 @@ class DecathlonDataset(Randomizable, CacheDataset):
         root_dir: str,
         task: str,
         section: str,
-        transform: Callable[..., Any] = Compose([LoadNiftid(["image", "label"]), AddChanneld(["image", "label"])]),
+        transform: Callable[..., Any] = LoadNiftid(["image", "label"]),
         download: bool = False,
         seed: int = 0,
         val_frac: float = 0.2,
diff --git a/monai/transforms/compose.py b/monai/transforms/compose.py
index 0fcbb7c1..f8ef4c2c 100644
--- a/monai/transforms/compose.py
+++ b/monai/transforms/compose.py
@@ -203,9 +203,7 @@ class Compose(Randomizable):
     def __init__(self, transforms=None) -> None:
         if transforms is None:
             transforms = []
-        if not isinstance(transforms, (list, tuple)):
-            raise ValueError("Parameters 'transforms' must be a list or tuple.")
-        self.transforms = transforms
+        self.transforms = ensure_tuple(transforms)
         self.set_random_state(seed=get_seed())
 
     def set_random_state(self, seed: Optional[int] = None, state: Optional[np.random.RandomState] = None):


Test patch:
diff --git a/tests/test_decathlondataset.py b/tests/test_decathlondataset.py
index 99fa32a6..a293bea5 100644
--- a/tests/test_decathlondataset.py
+++ b/tests/test_decathlondataset.py
@@ -53,6 +53,8 @@ class TestDecathlonDataset(unittest.TestCase):
             root_dir=tempdir, task="Task04_Hippocampus", transform=transform, section="validation", download=False
         )
         _test_dataset(data)
+        data = DecathlonDataset(root_dir=tempdir, task="Task04_Hippocampus", section="validation", download=False)
+        self.assertTupleEqual(data[0]["image"].shape, (33, 47, 34))
         shutil.rmtree(os.path.join(tempdir, "Task04_Hippocampus"))
         try:
             data = DecathlonDataset(
diff --git a/tests/test_mednistdataset.py b/tests/test_mednistdataset.py
index 9d252a57..4092fb05 100644
--- a/tests/test_mednistdataset.py
+++ b/tests/test_mednistdataset.py
@@ -43,6 +43,8 @@ class TestMedNISTDataset(unittest.TestCase):
         _test_dataset(data)
         data = MedNISTDataset(root_dir=tempdir, transform=transform, section="test", download=False)
         _test_dataset(data)
+        data = MedNISTDataset(root_dir=tempdir, section="test", download=False)
+        self.assertTupleEqual(data[0]["image"].shape, (64, 64))
         shutil.rmtree(os.path.join(tempdir, "MedNIST"))
         try:
             data = MedNISTDataset(root_dir=tempdir, transform=transform, section="test", download=False)