class_docstr: Interface is Gradio's main high-level class, and allows you to create a web-based GUI / demo
  around a machine learning model (or any Python function) in a few lines of code.
  You must specify three parameters: (1) the function to create a GUI for (2) the desired input components and
  (3) the desired output components. Additional parameters can be used to control the appearance
  and behavior of the demo.
  
  Example:
      import gradio as gr
  
      def image_classifier(inp):
          return {'cat': 0.3, 'dog': 0.7}
  
      demo = gr.Interface(fn=image_classifier, inputs="image", outputs="label")
      demo.launch()
  Demos: hello_world, hello_world_3, gpt2_xl
  Guides: quickstart, key-features, sharing-your-app, interface-state, reactive-interfaces, advanced-interface-features, setting-up-a-gradio-demo-for-maximum-performance
code: def attach_submit_events(
      self, submit_btn: Button | None, stop_btn: Button | None
  ):
      if self.live:
          if self.interface_type == InterfaceTypes.OUTPUT_ONLY:
              if submit_btn is None:
                  raise RenderError("Submit button not rendered")
              super().load(self.fn, None, self.output_components)
              # For output-only interfaces, the user probably still want a "generate"
              # button even if the Interface is live
              submit_btn.click(
                  self.fn,
                  None,
                  self.output_components,
                  api_name=self.api_name,
                  preprocess=not (self.api_mode),
                  postprocess=not (self.api_mode),
                  batch=self.batch,
                  max_batch_size=self.max_batch_size,
              )
          else:
              events: list[Callable] = []
              for component in self.input_components:
                  if component.has_event("stream") and component.streaming:  # type: ignore
                      events.append(component.stream)  # type: ignore
                  elif component.has_event("change"):
                      events.append(component.change)  # type: ignore
              on(
                  events,
                  self.fn,
                  self.input_components,
                  self.output_components,
                  api_name=self.api_name,
                  preprocess=not (self.api_mode),
                  postprocess=not (self.api_mode),
              )
      else:
          if submit_btn is None:
              raise RenderError("Submit button not rendered")
          fn = self.fn
          extra_output = []
  
          triggers = [submit_btn.click] + [
              component.submit  # type: ignore
              for component in self.input_components
              if component.has_event(Events.submit)
          ]
  
          if stop_btn:
              extra_output = [submit_btn, stop_btn]
  
              def cleanup():
                  return [Button(visible=True), Button(visible=False)]
  
              predict_event = on(
                  triggers,
                  lambda: (
                      Button(visible=False),
                      Button(visible=True),
                  ),
                  inputs=None,
                  outputs=[submit_btn, stop_btn],
                  queue=False,
                  show_api=False,
              ).then(
                  self.fn,
                  self.input_components,
                  self.output_components,
                  api_name=self.api_name,
                  scroll_to_output=True,
                  preprocess=not (self.api_mode),
                  postprocess=not (self.api_mode),
                  batch=self.batch,
                  max_batch_size=self.max_batch_size,
                  concurrency_limit=self.concurrency_limit,
              )
  
              predict_event.then(
                  cleanup,
                  inputs=None,
                  outputs=extra_output,  # type: ignore
                  queue=False,
                  show_api=False,
              )
  
              stop_btn.click(
                  cleanup,
                  inputs=None,
                  outputs=[submit_btn, stop_btn],
                  cancels=predict_event,
                  queue=False,
                  show_api=False,
              )
          else:
              on(
                  triggers,
                  fn,
                  self.input_components,
                  self.output_components,
                  api_name=self.api_name,
                  scroll_to_output=True,
                  preprocess=not (self.api_mode),
                  postprocess=not (self.api_mode),
                  batch=self.batch,
                  max_batch_size=self.max_batch_size,
                  concurrency_limit=self.concurrency_limit,
              )
  
imports: from __future__ import annotations
  import inspect
  import json
  import os
  import warnings
  import weakref
  from typing import TYPE_CHECKING, Any, Callable, Literal
  from gradio_client.documentation import document, set_documentation_group
  from gradio import Examples, utils
  from gradio.blocks import Blocks
  from gradio.components import Button, ClearButton, Component, DuplicateButton, Markdown, State, get_component_instance
  from gradio.data_classes import InterfaceTypes
  from gradio.events import Events, on
  from gradio.exceptions import RenderError
  from gradio.flagging import CSVLogger, FlaggingCallback, FlagMethod
  from gradio.layouts import Accordion, Column, Row, Tab, Tabs
  from gradio.pipelines import load_from_pipeline
  from gradio.themes import ThemeClass
label_desc: Use image node_id 9 for calling the Interface obj's underlying member method code with example usage: obj.attach_submit_events(submit_btn, stop_btn) and returns: list