docstr: Retrieves the asset and returns a dictionary with meta information, asset
  origin (from cache) and local path
docstr_tok: ["Retrieves","the","asset","and","returns","a","dictionary","with","meta","information",",","asset","origin","(","from","cache",")","and","local","path"]
code: def download(self, name, version, destination):
      """
      Retrieves the asset and returns a dictionary with meta information, asset
      origin (from cache) and local path
      """
      with ContextualizedLogging(name=name, version=version):
          destination_path = os.path.join(
              destination, *name.split("/"), version
          )
          object_name = self.get_object_name(name, version)
          meta = self.get_asset_meta(name, version)
  
          if meta.get("is_directory"):
              logger.info(
                  "Downloading remote multi-part asset",
                  n_parts=len(meta["contents"]),
              )
              t0 = time.monotonic()
              for part_no, part in enumerate(meta["contents"]):
                  current_destination_path = os.path.join(
                      destination_path, *part.split("/")
                  )
                  os.makedirs(
                      os.path.dirname(current_destination_path),
                      exist_ok=True,
                  )
                  remote_part_name = "/".join(
                      x
                      for x in object_name.split("/") + part.split("/")
                      if x
                  )
                  logger.debug(
                      "Downloading asset part",
                      part_no=part_no,
                      n_parts=len(meta["contents"]),
                  )
                  self.driver.download_object(
                      remote_part_name, current_destination_path
                  )
                  size = get_size(current_destination_path)
                  logger.debug(
                      "Downloaded asset part",
                      part_no=part_no,
                      n_parts=len(meta["contents"]),
                      size=humanize.naturalsize(size),
                      size_bytes=size,
                  )
              size = get_size(destination_path)
              logger.info(
                  "Downloaded remote multi-part asset",
                  size=humanize.naturalsize(size),
                  size_bytes=size,
              )
          else:
              logger.info("Downloading remote asset")
              t0 = time.monotonic()
              os.makedirs(
                  os.path.dirname(destination_path), exist_ok=True
              )
              self.driver.download_object(object_name, destination_path)
              size = get_size(destination_path)
              download_time = time.monotonic() - t0
              logger.info(
                  "Downloaded asset",
                  size=humanize.naturalsize(size),
                  time=humanize.naturaldelta(
                      datetime.timedelta(seconds=download_time)
                  ),
                  time_seconds=download_time,
                  size_bytes=size,
              )
          # return
          return {"path": destination_path, "meta": meta}
  
imports: import datetime
  import glob
  import json
  import os
  import tempfile
  import time
  from typing import Any, Optional
  import humanize
  from dateutil import parser, tz
  from structlog import get_logger
  from modelkit.assets import errors
  from modelkit.assets.drivers.abc import StorageDriver
  from modelkit.assets.drivers.local import LocalStorageDriver, LocalStorageDriverSettings
  from modelkit.assets.settings import AssetSpec
  from modelkit.utils.logging import ContextualizedLogging
label_desc: Use image node_id 10 for calling the StorageProvider obj's underlying member method code with example usage: obj.download(name, version, destination) and returns: dict