docstr: Determine if data is missing from the bundle and attempt to ingest it.
  
  Parameters
  ----------
  assets: list[TradingPair]
  data_frequency: str
  start_dt: pd.Timestamp
  end_dt: pd.Timestamp
  show_progress: bool
  show_breakdown: bool
docstr_tok: ["Determine","if","data","is","missing","from","the","bundle","and","attempt","to","ingest","it",".","Parameters","--","--","--","--","--","assets",":","list","[","TradingPair","]","data_frequency",":","str","start_dt",":","pd.Timestamp","end_dt",":","pd.Timestamp","show_progress",":","bool","show_breakdown",":","bool"]
code: def ingest_assets(
      self,
      assets,
      data_frequency,
      start_dt=None,
      end_dt=None,
      show_progress=False,
      show_breakdown=False,
      show_report=False,
  ):
      """
      Determine if data is missing from the bundle and attempt to ingest it.
  
      Parameters
      ----------
      assets: list[TradingPair]
      data_frequency: str
      start_dt: pd.Timestamp
      end_dt: pd.Timestamp
      show_progress: bool
      show_breakdown: bool
  
      """
      if start_dt is None:
          start_dt = self.calendar.first_session
  
      if end_dt is None:
          end_dt = pd.Timestamp.utcnow()
  
      get_start_end = (
          get_month_start_end
          if data_frequency == "minute"
          else get_year_start_end
      )
  
      # Assign the first and last day of the period
      start_dt, _ = get_start_end(start_dt)
      _, end_dt = get_start_end(end_dt)
  
      chunks = self.prepare_chunks(
          assets=assets,
          data_frequency=data_frequency,
          start_dt=start_dt,
          end_dt=end_dt,
      )
  
      problems = []
      # This is the common writer for the entire exchange bundle
      # we want to give an end_date far in time
      writer = self.get_writer(start_dt, end_dt, data_frequency)
      if show_breakdown:
          if chunks:
              for asset in chunks:
                  with maybe_show_progress(
                      chunks[asset],
                      show_progress,
                      label="Ingesting {frequency} price data for "
                      "{symbol} on {exchange}".format(
                          exchange=self.exchange_name,
                          frequency=data_frequency,
                          symbol=asset.symbol,
                      ),
                  ) as it:
                      for chunk in it:
                          problems += self.ingest_ctable(
                              asset=chunk["asset"],
                              data_frequency=data_frequency,
                              period=chunk["period"],
                              writer=writer,
                              empty_rows_behavior="strip",
                              cleanup=True,
                          )
      else:
          all_chunks = list(chain.from_iterable(itervalues(chunks)))
          # We sort the chunks by end date to ingest most recent data first
          if all_chunks:
              all_chunks.sort(
                  key=lambda chunk: pd.to_datetime(chunk["period"])
              )
              with maybe_show_progress(
                  all_chunks,
                  show_progress,
                  label="Ingesting {frequency} price data on "
                  "{exchange}".format(
                      exchange=self.exchange_name,
                      frequency=data_frequency,
                  ),
              ) as it:
                  for chunk in it:
                      problems += self.ingest_ctable(
                          asset=chunk["asset"],
                          data_frequency=data_frequency,
                          period=chunk["period"],
                          writer=writer,
                          empty_rows_behavior="strip",
                          cleanup=True,
                      )
  
      if show_report and len(problems) > 0:
          log.info(
              "problems during ingestion:{}\n".format(
                  "\n".join(problems)
              )
          )
  
imports: import os
  import shutil
  from datetime import timedelta
  from functools import partial
  from itertools import chain
  from operator import is_not
  import numpy
  import pandas
  import pytz
  from catalyst import get_calendar
  from catalyst.assets._assets import TradingPair
  from catalyst.constants import DATE_TIME_FORMAT, AUTO_INGEST
  from catalyst.constants import LOG_LEVEL
  from catalyst.data.minute_bars import BcolzMinuteOverlappingData, BcolzMinuteBarMetadata
  from catalyst.exchange.exchange_bcolz import BcolzExchangeBarReader, BcolzExchangeBarWriter
  from catalyst.exchange.exchange_errors import EmptyValuesInBundleError, TempBundleNotFoundError, NoDataAvailableOnExchange, PricingDataNotLoadedError, DataCorruptionError, PricingDataValueError
  from catalyst.exchange.utils.bundle_utils import range_in_bundle, get_bcolz_chunk, get_df_from_arrays, get_assets
  from catalyst.exchange.utils.datetime_utils import get_start_dt, get_period_label, get_month_start_end, get_year_start_end
  from catalyst.exchange.utils.exchange_utils import get_exchange_folder, save_exchange_symbols, mixin_market_params, get_catalyst_symbol
  from catalyst.utils.cli import maybe_show_progress
  from catalyst.utils.paths import ensure_directory
  from logbook import Logger
  from pytz import UTC
  from six import itervalues
label_desc: Use image node_id 14 for calling the ExchangeBundle obj's underlying member method code with example usage: obj.ingest_assets(assets, data_frequency, start_dt, end_dt, show_progress, show_breakdown, show_report) without return types