def download_and_prepare(
        self,
        dataset_dir,
        split=None,
        splits=None,
        cleanup=True,
    ):
        """Downloads the dataset and prepares it for use.

        If the requested splits have already been downloaded, they are not
        re-downloaded.

        Args:
            dataset_dir: the directory in which to construct the dataset
            split (None) a split to download, if applicable. If neither
                ``split`` nor ``splits`` are provided, the full dataset is
                downloaded
            splits (None): a list of splits to download, if applicable. If
                neither ``split`` nor ``splits`` are provided, the full dataset
                is  downloaded
            cleanup (True): whether to cleanup any temporary files generated
                during download

        Returns:
            the :class:`ZooDatasetInfo` for the dataset
        """

        # Parse splits
        splits = _parse_splits(split, splits)
        if splits:
            for split in splits:
                if split not in self.supported_splits:
                    raise ValueError(
                        "Invalid split '%s'; supported values are %s"
                        % (split, self.supported_splits)
                    )
        elif self.has_splits:
            splits = self.supported_splits

        # Load existing ZooDatasetInfo, if available
        info_path = self.get_info_path(dataset_dir)
        if os.path.isfile(info_path):
            info = ZooDatasetInfo.from_json(
                info_path,
                zoo_dataset=self,
                upgrade=True,
                warn_deprecated=True,
            )
        else:
            info = None

        scratch_dir = os.path.join(dataset_dir, "tmp-download")
        write_info = False

        # Download dataset, if necessary
        if splits:
            # Handle already downloaded splits
            if info is not None:
                download_splits = self._get_splits_to_download(
                    splits, dataset_dir, info
                )
            else:
                download_splits = splits

            # Download necessary splits
            for split in download_splits:
                split_dir = self.get_split_dir(dataset_dir, split)

                if self.supports_partial_downloads:
                    suffix = " if necessary"
                else:
                    suffix = ""

                if self.requires_manual_download:
                    logger.info(
                        "Preparing split '%s' in '%s'%s",
                        split,
                        split_dir,
                        suffix,
                    )
                else:
                    logger.info(
                        "Downloading split '%s' to '%s'%s",
                        split,
                        split_dir,
                        suffix,
                    )

                (
                    dataset_type,
                    num_samples,
                    classes,
                ) = self._download_and_prepare(split_dir, scratch_dir, split)

                # Add split to ZooDatasetInfo
                if info is None:
                    info = ZooDatasetInfo(
                        self, dataset_type, 0, classes=classes
                    )

                if classes and not info.classes:
                    info.classes = classes

                if self.supports_partial_downloads and num_samples is None:
                    logger.info(
                        "Existing download of split '%s' is sufficient", split
                    )
                    write_info = False
                else:
                    split_info = ZooDatasetSplitInfo(split, num_samples)
                    info.add_split(split_info)
                    write_info = True
        else:
            # Handle already downloaded datasets
            if not self._is_dataset_ready(dataset_dir, info):
                if self.supports_partial_downloads:
                    suffix = " if necessary"
                else:
                    suffix = ""

                if self.requires_manual_download:
                    logger.info(
                        "Preparing dataset in '%s'%s", dataset_dir, suffix
                    )
                else:
                    logger.info(
                        "Downloading dataset to '%s'%s", dataset_dir, suffix
                    )

                (
                    dataset_type,
                    num_samples,
                    classes,
                ) = self._download_and_prepare(dataset_dir, scratch_dir, None)

                if self.supports_partial_downloads and num_samples is None:
                    logger.info("Existing download is sufficient")
                    write_info = False
                else:
                    info = ZooDatasetInfo(
                        self, dataset_type, num_samples, classes=classes
                    )
                    write_info = True

        if write_info:
            info.write_json(info_path, pretty_print=True)
            logger.info("Dataset info written to '%s'", info_path)

        if cleanup:
            etau.delete_dir(scratch_dir)

        return info
Downloads the dataset and prepares it for use.

        If the requested splits have already been downloaded, they are not
        re-downloaded.

        Args:
            dataset_dir: the directory in which to construct the dataset
            split (None) a split to download, if applicable. If neither
                ``split`` nor ``splits`` are provided, the full dataset is
                downloaded
            splits (None): a list of splits to download, if applicable. If
                neither ``split`` nor ``splits`` are provided, the full dataset
                is  downloaded
            cleanup (True): whether to cleanup any temporary files generated
                during download

        Returns:
            the :class:`ZooDatasetInfo` for the dataset
        
fiftyone/zoo/datasets/__init__.py