code: def place(
      self,
      data_table_uri: str,
      search_keys: Dict[str, SearchKey],
      secondary_search_keys: Optional[Dict[str, SearchKey]] = None,
      sort_column: Optional[str] = None,
      date_format: Optional[str] = None,
      exclude_columns: Optional[List[str]] = None,
      hash_feature_names=False,
      snapshot_frequency_days: Optional[int] = None,
      features_for_embeddings: Optional[
          List[str]
      ] = DEFAULT_GENERATE_EMBEDDINGS,
      data_table_id_to_replace: Optional[str] = None,
      exclude_from_autofe_generation: Optional[List[str]] = None,
      _force_generation=False,
      _silent=False,
  ) -> str:
      trace_id = str(uuid.uuid4())
  
      with MDC(trace_id=trace_id):
          task_id = None
          try:
              if (
                  data_table_uri is None
                  or not data_table_uri.startswith("bq://")
              ):
                  raise ValidationError(
                      "Unsupported data table uri. It should looks like bq://projectId.datasetId.tableId"
                  )
              if search_keys is None or len(search_keys) == 0:
                  raise ValidationError("Empty search keys")
              if (
                  SearchKey.DATE in search_keys.values()
                  and date_format is None
              ):
                  raise ValidationError(
                      "date_format is required for DATE search key"
                  )
  
              request = {
                  "dataTableUri": data_table_uri,
                  "searchKeys": {
                      k: v.value.value for k, v in search_keys.items()
                  },
                  "dateFormat": date_format,
                  "excludeColumns": exclude_columns,
                  "hashFeatureNames": str(hash_feature_names).lower(),
                  "snapshotFrequencyDays": snapshot_frequency_days,
                  "featuresForEmbeddings": features_for_embeddings,
                  "forceGeneration": str(_force_generation).lower(),
              }
              if secondary_search_keys is not None:
                  request["secondarySearchKeys"] = {
                      k: v.value.value
                      for k, v in secondary_search_keys.items()
                  }
              if sort_column is not None:
                  request["sortColumn"] = sort_column
              if data_table_id_to_replace is not None:
                  request[
                      "adsDefinitionIdToReplace"
                  ] = data_table_id_to_replace
              if exclude_from_autofe_generation is not None:
                  request[
                      "excludeFromGeneration"
                  ] = exclude_from_autofe_generation
              self.logger.info(
                  f"Start registering data table {request}"
              )
  
              task_id = self._rest_client.register_ads(
                  request, trace_id
              )
              msg = f"Data table management task created. task_id={task_id}"
              self.logger.info(msg)
              print(msg)
  
              def poll():
                  status_response = (
                      self._rest_client.poll_ads_management_task_status(
                          task_id, trace_id
                      )
                  )
                  while (
                      status_response["status"]
                      not in self.FINAL_STATUSES
                  ):
                      time.sleep(5)
                      status_response = self._rest_client.poll_ads_management_task_status(
                          task_id, trace_id
                      )
                  return status_response
  
              if not _silent:
                  with Spinner():
                      status_response = poll()
              else:
                  status_response = poll()
  
              if status_response["status"] != "COMPLETED":
                  if (
                      "Cost of features generation exceeded the limit"
                      in status_response["errorMessage"]
                  ):
                      print(status_response["errorMessage"])
  
                      import ipywidgets as widgets
                      from IPython.display import display
  
                      button = widgets.Button(
                          description="Start registration with forced generation"
                      )
  
                      display(button)
  
                      def on_button_clicked(b):
                          self.place(
                              data_table_uri,
                              search_keys,
                              secondary_search_keys,
                              sort_column,
                              date_format,
                              exclude_columns,
                              hash_feature_names,
                              snapshot_frequency_days,
                              features_for_embeddings,
                              data_table_id_to_replace,
                              exclude_from_autofe_generation,
                              True,
                              _silent,
                          )
  
                      button.on_click(on_button_clicked)
                      return
                  else:
                      raise Exception(
                          "Failed to register ADS: "
                          + status_response["errorMessage"]
                      )
  
              data_table_id = status_response["adsDefinitionId"]
              msg = f"Data table successfully registered with id: {data_table_id}"
              self.logger.info(msg)
              print(msg)
              return data_table_id
          except KeyboardInterrupt:
              if task_id is not None:
                  msg = f"Stopping AdsManagementTask {task_id}"
                  print(msg)
                  self.logger.info(msg)
                  self._rest_client.stop_ads_management_task(
                      task_id, trace_id
                  )
          except Exception:
              self.logger.exception("Failed to register data table")
              raise
  
imports: import logging
  import time
  import uuid
  from datetime import datetime
  from enum import Enum
  from typing import Dict, List, Optional, Union
  from upgini.errors import HttpError, ValidationError
  from upgini.http import LoggerFactory, get_rest_client
  from upgini.mdc import MDC
  from upgini.metadata import SearchKey
  from upgini.spinner import Spinner
label_desc: Use image node_id 2 for calling the DataSourcePublisher obj's underlying member method code with example usage: obj.place(data_table_uri, search_keys, secondary_search_keys, sort_column, date_format, exclude_columns, hash_feature_names, snapshot_frequency_days, features_for_embeddings, data_table_id_to_replace, exclude_from_autofe_generation, _force_generation, _silent) and returns: data_table_id, status_response