code: def dbscan_fit(
      g: Any,
      dbscan: Any,
      kind: str = "nodes",
      cols: Optional[Union[List, str]] = None,
      use_umap_embedding: bool = True,
      target: bool = False,
      verbose: bool = False,
  ):
      """
      Fits clustering on UMAP embeddings if umap is True, otherwise on the features dataframe
          or target dataframe if target is True.
  
      Args:
          :g: graphistry graph
          :kind: 'nodes' or 'edges'
          :cols: list of columns to use for clustering given `g.featurize` has been run
          :use_umap_embedding: whether to use UMAP embeddings or features dataframe for clustering (default: True)
      """
      X = get_model_matrix(g, kind, cols, use_umap_embedding, target)
  
      if X.empty:
          raise ValueError("No features found for clustering")
  
      dbscan.fit(X)
      # this is a future feature one cuml supports it
      if g.engine_dbscan == "cuml":
          labels = dbscan.labels_.to_numpy()
          # dbscan.components_ = X[dbscan.core_sample_indices_.to_pandas()]  # can't believe len(samples) != unique(labels) ... #cumlfail
      else:
          labels = dbscan.labels_
  
      if kind == "nodes":
          g._nodes = g._nodes.assign(_dbscan=labels)
      elif kind == "edges":
          g._edges = g._edges.assign(_dbscan=labels)
      else:
          raise ValueError("kind must be one of `nodes` or `edges`")
  
      kind = "node" if kind == "nodes" else "edge"
      setattr(g, f"_{kind}_dbscan", dbscan)
  
      if (
          cols is not None
      ):  # set False since we used the features for verbose
          use_umap_embedding = False
  
      if verbose:
          cnt = Counter(labels)
          message = f"DBSCAN found {len(cnt)} clusters with {cnt[-1]} outliers"
          print()
          print("-" * len(message))
          print(message)
          print(
              f"--fit on {'umap embeddings' if use_umap_embedding else 'feature embeddings'} of size {X.shape}"
          )
          print("-" * len(message))
  
      return g
  
imports: import logging
  import pandas
  import numpy
  from typing import Any, List, Union, TYPE_CHECKING, Tuple, Optional
  from typing_extensions import Literal
  from collections import Counter
  from graphistry.Plottable import Plottable
  from graphistry.constants import CUML, UMAP_LEARN, DBSCAN
  from graphistry.features import ModelDict
  from graphistry.feature_utils import get_matrix_by_column_parts
label_desc: Use image node_id 6 for calling a global function with example usage: dbscan_fit(g, dbscan, kind, cols, use_umap_embedding, target, verbose) and returns: g