code: def generate_app_full(  # noqa: C901
      url_base_pathname=None,
      requests_pathname_prefix=None,
      routes_pathname_prefix=None,
  ):
      """Generates the Dash application including callbacks.
  
      Returns:
          The dash app itself.
      """
  
      _log.info("Generating full dash")
  
      # Initialize
      app = UDash(
          __name__,
          url_base_pathname=url_base_pathname,
          requests_pathname_prefix=requests_pathname_prefix,
          routes_pathname_prefix=routes_pathname_prefix,
      )
      app.scripts.config.serve_locally = True
      app.css.config.serve_locally = True
      app.config["suppress_callback_exceptions"] = True
      app.logger.handlers = []
      app.title = "InterpretML"
      server = app.server
  
      # Define layout
      app.layout = html.Div(
          [
              html.Div(
                  [html.H2("Interpret ML Dashboard")],
                  className="banner",
              ),
              html.Div(
                  dcc.Tabs(
                      id="tabs",
                      children=[
                          dcc.Tab(
                              label="Overview",
                              value="overview",
                              children=html.Div(
                                  id="overview-tab", className="contain"
                              ),
                          ),
                          dcc.Tab(
                              label="Data",
                              value="data",
                              children=html.Div(
                                  id="data-tab", className="contain"
                              ),
                          ),
                          dcc.Tab(
                              label="Performance",
                              value="perf",
                              children=html.Div(
                                  id="perf-tab", className="contain"
                              ),
                          ),
                          dcc.Tab(
                              label="Global",
                              value="global",
                              children=html.Div(
                                  id="global-tab", className="contain"
                              ),
                          ),
                          dcc.Tab(
                              label="Local",
                              value="local",
                              children=html.Div(
                                  id="local-tab", className="contain"
                              ),
                          ),
                      ],
                      vertical=False,
                      mobile_breakpoint=480,
                      value="overview",
                  )
              ),
              # NOTE: Workaround for tables not rendering
              html.Div(
                  dt.DataTable(data=[{}]), style={"display": "none"}
              ),
          ],
          className="app",
      )
  
      def get_model_records(ctx):
          """Extracts model records passed to Dash.
  
          Args:
              ctx: List of explanations.
  
          Returns:
              List of dictionaries denoting name and type of explanations.
          """
          _types = {
              "data": "Data",
              "perf": "Performance",
              "global": "Global",
              "local": "Local",
          }
          return [
              {
                  # 'Index': i,
                  "Name": ctx[i][0].name,
                  "Type": _types[ctx[i][0].explanation_type],
              }
              for i in range(len(ctx))
          ]
  
      def gen_overview_tab():
          """Generates overview tab.
  
          Returns:
              Dash component that handles overview tab entire.
          """
  
          # Define components
          ctx = app.ctx
          records = get_model_records(ctx)
          columns = [
              {"name": "Name", "id": "Name"},
              {"name": "Type", "id": "Type"},
          ]
          table = dt.DataTable(
              data=records,
              columns=columns,
              row_selectable=False,
              **DATA_TABLE_DEFAULTS,
          )
          markdown = """
  Welcome to Interpret ML's dashboard. Here you will find en-masse visualizations for your machine learning pipeline.
  
  ***
  
  The explanations available are split into tabs, each covering an aspect of the pipeline.
  - **Data** covers exploratory data analysis, designed mostly for feature-level.
  - **Performance** covers model performance both overall and user-defined groups.
  - **Global** explains model decisions overall.
  - **Local** explains a model decision for every instance/observation.
  """
  
          # Wrap as cards.
          cards = []
          cards.append(
              html.Div(
                  [
                      html.Div(
                          html.Div(
                              "Introduction", className="card-title"
                          ),
                          className="card-header",
                      ),
                      html.Div(
                          dcc.Markdown(markdown), className="card-body"
                      ),
                  ],
                  className="card",
              )
          )
          cards.append(
              html.Div(
                  [
                      html.Div(
                          html.Div(
                              "Available Explanations",
                              className="card-title",
                          ),
                          className="card-header",
                      ),
                      html.Div(html.Div(table), className="card-body"),
                  ],
                  className="card",
              )
          )
  
          return html.Div(cards)
  
      def gen_tab(explanation_type):
          _log.debug("Generating tab: {0}".format(explanation_type))
          ctx = app.ctx
          options = app.options
          data_options = [
              {"label": ctx[i][0].name, "value": i}
              for i in range(len(ctx))
              if ctx[i][0].explanation_type == explanation_type
          ]
          indices = html.Div(
              [
                  html.Div(
                      id="{0}-instance-idx-{1}".format(
                          explanation_type, str(i)
                      ),
                      className="hdn",
                  )
                  for i in range(MAX_NUM_PANES)
              ]
          )
          specific_indices = html.Div(
              [
                  html.Div(
                      id="{0}-specific-idx-{1}".format(
                          explanation_type, str(i)
                      ),
                      className="hdn",
                  )
                  for i in range(MAX_NUM_PANES)
              ]
          )
          shared_indices = html.Div(
              [
                  html.Div(
                      id="{0}-shared-idx".format(explanation_type),
                      className="hdn",
                  )
              ]
          )
  
          # NOTE: Don't question this. It was written in blood.
          shared_value = options["share_tables"].get(
              explanation_type, False
          )
          shared_value = "True" if shared_value is True else None
          is_shared = html.Div(
              id="{0}-is-shared".format(explanation_type),
              children=shared_value,
              className="hdn",
          )
          _log.debug(
              "Tab {0} is_shared: {1}".format(
                  explanation_type, shared_value
              )
          )
          return html.Div(
              [
                  html.Div(
                      [
                          html.Div(
                              html.Div(
                                  "Select Explanation",
                                  className="card-title",
                              ),
                              className="card-header",
                          ),
                          html.Div(
                              [
                                  dcc.Dropdown(
                                      id="{0}-model-drop".format(
                                          explanation_type
                                      ),
                                      options=data_options,
                                      multi=True,
                                  )
                              ],
                              className="card-body",
                          ),
                      ],
                      className="card",
                  ),
                  is_shared,
                  indices,
                  shared_indices,
                  specific_indices,
                  html.Div(
                      id="{0}-shared-table-container".format(
                          explanation_type
                      )
                  ),
                  html.Div(
                      id="{0}-tabs-container".format(explanation_type)
                  ),
              ]
          )
  
      # Callback generators
  
      def register_pane_cb(explanation_type):
          def output_callback(value, is_shared):
              _log.debug(
                  "Registering pane: {0}|{1}|{2}".format(
                      explanation_type, value, is_shared
                  )
              )
              if value is None:
                  return None
  
              ctx = app.ctx
              components = []
  
              for i, model_idx in enumerate(value):
                  s_i = str(i)
  
                  df = ctx[model_idx][1]
                  if df is not None:
                      records = df.to_dict("records")
                      if is_shared is not None:
                          component = html.Div()
                      else:
                          columns = [
                              {"name": col, "id": col}
                              for _, col in enumerate(df.columns)
                              if col != "id"
                          ]
                          instance_table = dt.DataTable(
                              data=records,
                              columns=columns,
                              id="{0}-instance-table-{1}".format(
                                  explanation_type, s_i
                              ),
                              row_selectable="multi",
                              **DATA_TABLE_DEFAULTS,
                          )
                          component = html.Div(
                              [
                                  html.Div(
                                      html.Div(
                                          "Select Instances",
                                          className="card-title",
                                      ),
                                      className="card-header",
                                  ),
                                  html.Div(
                                      [html.Div([instance_table])],
                                      className="card-body card-table",
                                  ),
                              ],
                              className="card",
                          )
  
                      components.append(
                          html.Div(
                              [
                                  component,
                                  html.Div(
                                      id="{0}-plots-container-{1}".format(
                                          explanation_type, s_i
                                      )
                                  ),
                                  html.Div(
                                      id="{0}-overall-plot-container-{1}".format(
                                          explanation_type, s_i
                                      )
                                  ),
                              ],
                              className="gr-col",
                          )
                      )
                  else:
                      _log.info(
                          "No df provided in pane cb for model idx: {0}".format(
                              model_idx
                          )
                      )
                      components.append(
                          html.Div(
                              [
                                  html.Div(
                                      id="{0}-overall-plot-container-{1}".format(
                                          explanation_type, s_i
                                      )
                                  )
                              ],
                              className="gr-col",
                          )
                      )
              return html.Div(components, className="gr")
  
          return output_callback
  
      def register_update_share_table_cb(explanation_type):
          def output_callback(value, is_shared):
              if is_shared is None:
                  return None
  
              if value is None or len(value) == 0:
                  return None
              return gen_share_table_container(value, explanation_type)
  
          return output_callback
  
      def register_update_idx_cb():
          def output_callback(data, derived_virtual_selected_row_ids):
              if derived_virtual_selected_row_ids is None:
                  output = None
                  return output
              output = [
                  data[i]["id"]
                  for i in derived_virtual_selected_row_ids
              ]
              return output
  
          return output_callback
  
      def register_update_instance_idx_cb():
          def output_callback(
              is_shared, shared_indices, specific_indices
          ):
              if is_shared is not None:
                  return shared_indices
              else:
                  return specific_indices
  
          return output_callback
  
      def register_update_plots_cb(pane_idx):
          def output_callback(model_idx, instance_idx):
              if pane_idx >= len(model_idx):  # pragma: no cover
                  _log.warning(
                      "Pane index {} larger than selected explanations.".format(
                          pane_idx
                      )
                  )
                  return None
              _log.debug(
                  "Updating plots: {0}|{1}|{2}".format(
                      pane_idx, model_idx, instance_idx
                  )
              )
              return gen_plots_container(
                  model_idx[pane_idx], instance_idx
              )
  
          return output_callback
  
      def register_update_overall_plot_cb(pane_idx):
          def output_callback(model_idx, empty):
              if pane_idx >= len(model_idx):  # pragma: no cover
                  _log.warning(
                      "Pane index {} larger than selected explanations.".format(
                          pane_idx
                      )
                  )
                  return None
              _log.debug(
                  "Updating overall plots: {0}".format(model_idx)
              )
              return gen_overall_plot_container(model_idx[pane_idx])
  
          return output_callback
  
      # DYNAMIC
      tab_list = ["data", "perf", "global", "local"]
      for tab in tab_list:
          app.callback(
              Output("{0}-tabs-container".format(tab), "children"),
              [
                  Input("{0}-model-drop".format(tab), "value"),
                  Input("{0}-is-shared".format(tab), "children"),
              ],
          )(register_pane_cb(tab))
  
          for i in range(MAX_NUM_PANES):
              s_i = str(i)
              app.callback(
                  Output(
                      "{0}-plots-container-{1}".format(tab, s_i),
                      "children",
                  ),
                  [
                      Input("{0}-model-drop".format(tab), "value"),
                      Input(
                          "{0}-instance-idx-{1}".format(tab, s_i),
                          "children",
                      ),
                  ],
              )(register_update_plots_cb(i))
              app.callback(
                  Output(
                      "{0}-overall-plot-container-{1}".format(tab, s_i),
                      "children",
                  ),
                  [
                      Input("{0}-model-drop".format(tab), "value"),
                      # NOTE: Fixes concurrency bug for panes. Find better solution.
                      Input(
                          "{0}-instance-idx-{1}".format(tab, s_i),
                          "children",
                      ),
                  ],
              )(register_update_overall_plot_cb(i))
  
          app.callback(
              Output(
                  "{0}-shared-table-container".format(tab), "children"
              ),
              [
                  Input("{0}-model-drop".format(tab), "value"),
                  Input("{0}-is-shared".format(tab), "children"),
              ],
          )(register_update_share_table_cb(tab))
  
          app.callback(
              Output("{0}-shared-idx".format(tab), "children"),
              [
                  Input("{0}-shared-table".format(tab), "data"),
                  Input(
                      "{0}-shared-table".format(tab),
                      "derived_virtual_selected_row_ids",
                  ),
              ],
          )(register_update_idx_cb())
          for i in range(MAX_NUM_PANES):
              s_i = str(i)
              app.callback(
                  Output(
                      "{0}-instance-idx-{1}".format(tab, s_i),
                      "children",
                  ),
                  [
                      Input("{0}-is-shared".format(tab), "children"),
                      Input("{0}-shared-idx".format(tab), "children"),
                      Input(
                          "{0}-specific-idx-{1}".format(tab, s_i),
                          "children",
                      ),
                  ],
              )(register_update_instance_idx_cb())
              app.callback(
                  Output(
                      "{0}-specific-idx-{1}".format(tab, s_i),
                      "children",
                  ),
                  [
                      Input(
                          "{0}-instance-table-{1}".format(tab, s_i),
                          "data",
                      ),
                      Input(
                          "{0}-instance-table-{1}".format(tab, s_i),
                          "derived_virtual_selected_row_ids",
                      ),
                  ],
              )(register_update_idx_cb())
  
      def gen_share_table_container(model_idxs, explanation_type):
          _log.debug(
              "Generating shared table container: {0}|{1}".format(
                  model_idxs, explanation_type
              )
          )
  
          # Since tables are shared (identical in content), we take the first.
          model_idx = model_idxs[0]
          ctx = app.ctx
          df = ctx[model_idx][1]
          if df is not None:
              records = df.to_dict("records")
              columns = [
                  {"name": col, "id": col}
                  for _, col in enumerate(df.columns)
                  if col != "id"
              ]
              instance_table = dt.DataTable(
                  data=records,
                  columns=columns,
                  id="{0}-shared-table".format(explanation_type),
                  row_selectable="multi",
                  **DATA_TABLE_DEFAULTS,
              )
              component = html.Div(
                  [
                      html.Div(
                          html.Div(
                              "Select Components to Graph",
                              className="card-title",
                          ),
                          className="card-header",
                      ),
                      html.Div(
                          [html.Div([instance_table])],
                          className="card-body card-table",
                      ),
                  ],
                  className="card",
              )
              return component
          else:
              return None
  
      def gen_plots_container(model_idx, picker_idx):
          if model_idx is None or not picker_idx:
              return None
  
          _log.debug(
              "Generating plots: {0}|{1}".format(model_idx, picker_idx)
          )
  
          ctx = app.ctx
          exp = ctx[model_idx][0]
  
          output = []
          counter = 0
          for picker in reversed(picker_idx):
              output_div = gen_plot(exp, picker, model_idx, counter)
              counter += 1
              output.append(output_div)
          return html.Div(output)
  
      def gen_overall_plot_container(model_idx):
          _log.debug("Generating overall plots: {0}".format(model_idx))
  
          ctx = app.ctx
          exp = ctx[model_idx][0]
  
          output_div = gen_overall_plot(exp, model_idx)
  
          return html.Div(output_div)
  
      @server.errorhandler(Exception)
      def handle_error(e):  # pragma: no cover
          _log.error(e, exc_info=True)
          return (
              "Internal Server Error caught by udash. See logs if available.",
              500,
          )
  
      @app.callback(
          Output("data-tab", "children"), [Input("tabs", "value")]
      )
      def update_data_tab_content(tab):
          if tab is None or tab != "data":
              return None
          return gen_tab(tab)
  
      @app.callback(
          Output("perf-tab", "children"), [Input("tabs", "value")]
      )
      def update_perf_tab_content(tab):
          if tab is None or tab != "perf":
              return None
          return gen_tab(tab)
  
      @app.callback(
          Output("overview-tab", "children"), [Input("tabs", "value")]
      )
      def update_overview_tab_content(tab):
          if tab is None or tab != "overview":
              return None
          return gen_overview_tab()
  
      @app.callback(
          Output("local-tab", "children"), [Input("tabs", "value")]
      )
      def update_local_tab_content(tab):
          if tab is None or tab != "local":
              return None
          return gen_tab(tab)
  
      @app.callback(
          Output("global-tab", "children"), [Input("tabs", "value")]
      )
      def update_global_tab_content(tab):
          if tab is None or tab != "global":
              return None
          return gen_tab(tab)
  
      _log.info("Generated full dash")
      return app
  
file_path: interpret/python/interpret-core/interpret/visual/_udash.py
imports: import dash
  from dash import html
  from dash import dcc
  from dash import dash_table
  import dash_cytoscape
  from dash.dependencies import Input, Output
  import dash.development.base_component
  from pandas.core.generic import NDFrame
  from plotly import graph_objs
  import logging
label_desc: Use image node_id 4 for calling a global function with example usage: generate_app_full(url_base_pathname, requests_pathname_prefix, routes_pathname_prefix) and returns: app, unknown, html, html, output_callback, output_callback, output_callback, output_callback, output_callback, output_callback, html, html, str,  int, gen_tab, gen_tab, gen_overview_tab, gen_tab, gen_tab, html, gen_share_table_container, output, gen_plots_container, gen_overall_plot_container, component, None, None, None, None, None, None, None, None, None, None, output, shared_indices, specific_indices, None, None