class_docstr: A DoFn that extracts slice keys that apply per example.
class_docstr_tok: ["A","DoFn","that","extracts","slice","keys","that","apply","per","example","."]
code: def process(
      self,
      element: types.Extracts,
      slice_spec: List[slicer.SingleSliceSpec],
  ) -> List[types.Extracts]:
      # Slice on transformed features if available.
      features_dicts = []
      if (
          constants.TRANSFORMED_FEATURES_KEY in element
          and element[constants.TRANSFORMED_FEATURES_KEY] is not None
      ):
          transformed_features = element[
              constants.TRANSFORMED_FEATURES_KEY
          ]
          # If only one model, the output is stored without keying on model name.
          if (
              not self._eval_config
              or len(self._eval_config.model_specs) == 1
          ):
              features_dicts.append(transformed_features)
          else:
              # Search for slices in each model's transformed features output.
              for spec in self._eval_config.model_specs:
                  if spec.name in transformed_features:
                      features_dicts.append(
                          transformed_features[spec.name]
                      )
      # Search for slices first in transformed features (if any). If a match is
      # not found there then search in raw features.
      slice_keys = list(
          slicer.get_slices_for_features_dicts(
              features_dicts,
              util.get_features_from_extracts(element),
              slice_spec,
          )
      )
  
      # If SLICE_KEY_TYPES_KEY already exists, that means the
      # SqlSliceKeyExtractor has generated some slice keys. We need to add
      # them to current slice_keys list.
      if (
          constants.SLICE_KEY_TYPES_KEY in element
          and element[constants.SLICE_KEY_TYPES_KEY]
      ):
          slice_keys.extend(element[constants.SLICE_KEY_TYPES_KEY])
  
      unique_slice_keys = list(set(slice_keys))
      if len(slice_keys) != len(unique_slice_keys):
          self._duplicate_slice_keys_counter.inc()
  
      # Make a a shallow copy, so we don't mutate the original.
      element_copy = copy.copy(element)
  
      element_copy[
          constants.SLICE_KEY_TYPES_KEY
      ] = slicer.slice_keys_to_numpy_array(unique_slice_keys)
      # Add a list of stringified slice keys to be materialized to output table.
      if self._materialize:
          element_copy[
              constants.SLICE_KEYS_KEY
          ] = types.MaterializedColumn(
              name=constants.SLICE_KEYS_KEY,
              value=(
                  list(
                      slicer.stringify_slice_key(x).encode("utf-8")
                      for x in unique_slice_keys
                  )
              ),
          )
      return [element_copy]
  
file_path: model-analysis/tensorflow_model_analysis/extractors/slice_key_extractor.py
imports: import copy
  from typing import List, Optional
  import apache_beam
  from tensorflow_model_analysis import constants
  from tensorflow_model_analysis.api import types
  from tensorflow_model_analysis.extractors import extractor
  from tensorflow_model_analysis.proto import config_pb2
  from tensorflow_model_analysis.slicer import slicer_lib
  from tensorflow_model_analysis.utils import util
label_desc: Use image node_id 2 for calling the ExtractSliceKeysFn obj's underlying member method code with example usage: obj.process(element, slice_spec) and returns: list