code: def progress(
      *futures,
      notebook=None,
      multi=True,
      complete=True,
      group_by="prefix",
      **kwargs,
  ):
      """Track progress of futures
  
      This operates differently in the notebook and the console
  
      *  Notebook:  This returns immediately, leaving an IPython widget on screen
      *  Console:  This blocks until the computation completes
  
      Parameters
      ----------
      futures : Futures
          A list of futures or keys to track
      notebook : bool (optional)
          Running in the notebook or not (defaults to guess)
      multi : bool (optional)
          Track different functions independently (defaults to True)
      complete : bool (optional)
          Track all keys (True) or only keys that have not yet run (False)
          (defaults to True)
      group_by : Callable | Literal["spans"] | Literal["prefix"]
          Use spans instead of task key names for grouping tasks
          (defaults to "prefix")
  
      Notes
      -----
      In the notebook, the output of `progress` must be the last statement
      in the cell. Typically, this means calling `progress` at the end of a
      cell.
  
      Examples
      --------
      >>> progress(futures)  # doctest: +SKIP
      [########################################] | 100% Completed |  1.7s
      """
      futures = futures_of(futures)
      if not isinstance(futures, (set, list)):
          futures = [futures]
      if notebook is None:
          notebook = (
              is_kernel()
          )  # often but not always correct assumption
      if kwargs.get("func", None) is not None:
          warnings.warn(
              "`func` is deprecated, use `group_by` instead",
              category=DeprecationWarning,
          )
          group_by = kwargs.pop("func")
      if group_by not in ("spans", "prefix") and not isinstance(
          group_by, Callable
      ):
          raise ValueError(
              "`group_by` should be 'spans', 'prefix', or a Callable"
          )
      if notebook:
          if multi:
              bar = MultiProgressWidget(
                  futures,
                  complete=complete,
                  group_by=group_by,
                  **kwargs,
              )
          else:
              bar = ProgressWidget(futures, complete=complete, **kwargs)
          return bar
      else:
          TextProgressBar(futures, complete=complete, **kwargs)
  
imports: from __future__ import annotations
  import html
  import logging
  import sys
  import warnings
  import weakref
  from contextlib import suppress
  from timeit import default_timer
  from typing import Callable
  from tlz import valmap
  from tornado.ioloop import IOLoop
  import dask
  from dask.utils import key_split
  from distributed.client import default_client, futures_of
  from distributed.core import CommClosedError, clean_exception, coerce_to_address, connect
  from distributed.diagnostics.progress import MultiProgress, Progress, format_time
  from distributed.protocol.pickle import dumps
  from distributed.utils import LoopRunner, is_kernel
label_desc: Use image node_id 2 for calling a global function with example usage: progress() and returns: bar