code: def csvdir_bundle(
      environ,
      asset_db_writer,
      minute_bar_writer,
      daily_bar_writer,
      adjustment_writer,
      calendar,
      start_session,
      end_session,
      cache,
      show_progress,
      output_dir,
      tframes=None,
      csvdir=None,
  ):
      """
      Build a zipline data bundle from the directory with csv files.
      """
      if not csvdir:
          csvdir = environ.get("CSVDIR")
          if not csvdir:
              raise ValueError("CSVDIR environment variable is not set")
  
      if not os.path.isdir(csvdir):
          raise ValueError("%s is not a directory" % csvdir)
  
      if not tframes:
          tframes = set(["daily", "minute"]).intersection(
              os.listdir(csvdir)
          )
  
          if not tframes:
              raise ValueError(
                  "'daily' and 'minute' directories "
                  "not found in '%s'" % csvdir
              )
  
      divs_splits = {
          "divs": DataFrame(
              columns=[
                  "sid",
                  "amount",
                  "ex_date",
                  "record_date",
                  "declared_date",
                  "pay_date",
              ]
          ),
          "splits": DataFrame(
              columns=["sid", "ratio", "effective_date"]
          ),
      }
      for tframe in tframes:
          ddir = os.path.join(csvdir, tframe)
  
          symbols = sorted(
              item.split(".csv")[0]
              for item in os.listdir(ddir)
              if ".csv" in item
          )
          if not symbols:
              raise ValueError(
                  "no <symbol>.csv* files found in %s" % ddir
              )
  
          dtype = [
              ("start_date", "datetime64[ns]"),
              ("end_date", "datetime64[ns]"),
              ("auto_close_date", "datetime64[ns]"),
              ("symbol", "object"),
          ]
          metadata = DataFrame(empty(len(symbols), dtype=dtype))
  
          if tframe == "minute":
              writer = minute_bar_writer
          else:
              writer = daily_bar_writer
  
          writer.write(
              _pricing_iter(
                  ddir, symbols, metadata, divs_splits, show_progress
              ),
              show_progress=show_progress,
          )
  
          # Hardcode the exchange to "CSVDIR" for all assets and (elsewhere)
          # register "CSVDIR" to resolve to the NYSE calendar, because these
          # are all equities and thus can use the NYSE calendar.
          metadata["exchange"] = "CSVDIR"
  
          asset_db_writer.write(equities=metadata)
  
          divs_splits["divs"]["sid"] = divs_splits["divs"][
              "sid"
          ].astype(int)
          divs_splits["splits"]["sid"] = divs_splits["splits"][
              "sid"
          ].astype(int)
          adjustment_writer.write(
              splits=divs_splits["splits"],
              dividends=divs_splits["divs"],
          )
  
file_path: zipline/zipline/data/bundles/csvdir.py
imports: import os
  import sys
  from logbook import Logger, StreamHandler
  from numpy import empty
  from pandas import DataFrame, read_csv, Index, Timedelta, NaT
  from trading_calendars import register_calendar_alias
  from zipline.utils.cli import maybe_show_progress
  from .None import core
label_desc: Use image node_id 2 for calling a global function with example usage: csvdir_bundle(environ, asset_db_writer, minute_bar_writer, daily_bar_writer, adjustment_writer, calendar, start_session, end_session, cache, show_progress, output_dir, tframes, csvdir) without return types