class_docstr: The main entry point to create a forecast.
  
  Call the :py:meth:`~greykite.framework.templates.forecaster.Forecaster.run_forecast_config`
  method to create a forecast. It takes a dataset and forecast configuration parameters.
  
  Notes
  -----
  This class can create forecasts using any of the model templates in
  `~greykite.framework.templates.model_templates.ModelTemplateEnum`.
  Model templates provide suitable default values for the available
  forecast estimators depending on the data characteristics.
  
  The model template is selected via the ``config.model_template``
  parameter to :py:meth:`~greykite.framework.templates.forecaster.Forecaster.run_forecast_config`.
  
  To add your own custom algorithms or template classes in our framework,
  pass ``model_template_enum`` and ``default_model_template_name``
  to the constructor.
class_docstr_tok: ["The","main","entry","point","to","create","a","forecast",".","Call","the",":","py",":","meth",":","`","~greykite.framework.templates.forecaster.Forecaster.run_forecast_config","`","method","to","create","a","forecast",".","It","takes","a","dataset","and","forecast","configuration","parameters",".","Notes","--","--","-","This","class","can","create","forecasts","using","any","of","the","model","templates","in","`","~greykite.framework.templates.model_templates.ModelTemplateEnum","`",".","Model","templates","provide","suitable","default","values","for","the","available","forecast","estimators","depending","on","the","data","characteristics",".","The","model","template","is","selected","via","the","``","config.model_template","``","parameter","to",":","py",":","meth",":","`","~greykite.framework.templates.forecaster.Forecaster.run_forecast_config","`",".","To","add","your","own","custom","algorithms","or","template","classes","in","our","framework",",","pass","``","model_template_enum","``","and","``","default_model_template_name","``","to","the","constructor","."]
docstr: Extracts template class (e.g. `SimpleSilverkiteTemplate`) from the config.
  
  Parameters
  ----------
  config : :class:`~greykite.framework.templates.model_templates.ForecastConfig` or None
      Config object for template class to use.
      See :class:`~greykite.framework.templates.model_templates.ForecastConfig`.
  
  Returns
  -------
  template_class : Type[`~greykite.framework.templates.template_interface.TemplateInterface`]
      An implementation of `~greykite.framework.templates.template_interface.TemplateInterface`.
docstr_tok: ["Extracts","template","class","(","e.g",".","`","SimpleSilverkiteTemplate","`",")","from","the","config",".","Parameters","--","--","--","--","--","config",":",":","class",":","`","~greykite.framework.templates.model_templates.ForecastConfig","`","or","None","Config","object","for","template","class","to","use",".","See",":","class",":","`","~greykite.framework.templates.model_templates.ForecastConfig","`",".","Returns","--","--","--","-","template_class",":","Type","[","`","~greykite.framework.templates.template_interface.TemplateInterface","`","]","An","implementation","of","`","~greykite.framework.templates.template_interface.TemplateInterface","`","."]
code: def __get_template_class(
      self, config: Optional[ForecastConfig] = None
  ) -> Type[TemplateInterface]:
      """Extracts template class (e.g. `SimpleSilverkiteTemplate`) from the config.
  
      Parameters
      ----------
      config : :class:`~greykite.framework.templates.model_templates.ForecastConfig` or None
          Config object for template class to use.
          See :class:`~greykite.framework.templates.model_templates.ForecastConfig`.
  
      Returns
      -------
      template_class : Type[`~greykite.framework.templates.template_interface.TemplateInterface`]
          An implementation of `~greykite.framework.templates.template_interface.TemplateInterface`.
      """
      config = (
          self.__get_config_with_default_model_template_and_components(
              config
          )
      )
  
      if isinstance(config.model_template, list):
          # Parses `config.model_template` to extract the template class, with validation.
          # Handles a list of model templates.
          template_classes = [
              self.__get_template_class(
                  config=ForecastConfig(model_template=mt)
              )
              for mt in config.model_template
          ]
          for tc in template_classes:
              if tc != template_classes[0]:
                  raise ValueError(
                      "All model templates must use the same template class. "
                      f"Found {template_classes}"
                  )
          template_class = template_classes[0]
          if not template_class().allow_model_template_list:
              raise ValueError(
                  f"The template class {template_class} does not allow `model_template` to be a list. "
                  f"Pass a string instead."
              )
      else:
          # Handles other situations (string, data class).
          try:
              # Tries to look up in `self.model_template_enum`.
              template_class = self.model_template_enum[
                  config.model_template
              ].value.template_class
          except (KeyError, TypeError):
              # Template is not found in the enum.
              # NB: The logic in this clause is written for the default `self.model_template_enum`,
              #   which contains only one template class that is a subclass of SimpleSilverkiteTemplate.
              #   If a custom `self.model_template_enum` is provided it may be useful to override this logic.
              valid_names = ", ".join(
                  self.model_template_enum.__dict__["_member_names_"]
              )
              # Checks if template enum has a template class that supports generic naming
              #   i.e. a subclass of `SimpleSilverkiteTemplate`.
              subclass_simple_silverkite = [
                  mte
                  for mte in self.model_template_enum
                  if issubclass(
                      mte.value.template_class, SimpleSilverkiteTemplate
                  )
              ]
              if len(subclass_simple_silverkite) > 0:
                  try:
                      log_message(
                          f"Model template {config.model_template} is not found in the template enum. "
                          f"Checking if model template is suitable for `SimpleSilverkiteTemplate`.",
                          LoggingLevelEnum.DEBUG,
                      )
                      SimpleSilverkiteTemplate().check_template_type(
                          config.model_template
                      )
                      possible_template_classes = (
                          unique_elements_in_list(
                              [
                                  mte.value.template_class
                                  for mte in subclass_simple_silverkite
                              ]
                          )
                      )
                      if len(possible_template_classes) > 1:
                          log_message(
                              f"Multiple template classes could be used for the model "
                              f"template {config.model_template}: {possible_template_classes}",
                              LoggingLevelEnum.DEBUG,
                          )
                      # arbitrarily take a class that supports generic naming
                      template_class = subclass_simple_silverkite[
                          0
                      ].value.template_class
                      log_message(
                          f"Using template class {template_class} for the model "
                          f"template {config.model_template}",
                          LoggingLevelEnum.DEBUG,
                      )
                  except ValueError:
                      raise ValueError(
                          f"Model Template '{config.model_template}' is not recognized! Must be one of: {valid_names}"
                          " or satisfy the `SimpleSilverkiteTemplate` rules."
                      )
              else:
                  raise ValueError(
                      f"Model Template '{config.model_template}' is not recognized! Must be one of: {valid_names}."
                  )
  
      # Validates `model_components_param` compatibility with the template
      if (
          not template_class().allow_model_components_param_list
          and isinstance(config.model_components_param, list)
      ):
          raise ValueError(
              f"Model template {config.model_template} does not support a list of `ModelComponentsParam`."
          )
  
      return template_class
  
imports: import json
  from copy import deepcopy
  from enum import Enum
  from typing import Dict
  from typing import Optional
  from typing import Type
  import pandas
  from greykite.common.logging import LoggingLevelEnum
  from greykite.common.logging import log_message
  from greykite.common.python_utils import unique_elements_in_list
  from greykite.framework.pipeline.pipeline import ForecastResult
  from greykite.framework.pipeline.pipeline import forecast_pipeline
  from greykite.framework.pipeline.utils import get_basic_pipeline
  from greykite.framework.templates.auto_model_template import get_auto_silverkite_model_template
  from greykite.framework.templates.autogen.forecast_config import ForecastConfig
  from greykite.framework.templates.autogen.forecast_config import forecast_config_from_dict
  from greykite.framework.templates.forecast_config_defaults import ForecastConfigDefaults
  from greykite.framework.templates.model_templates import ModelTemplateEnum
  from greykite.framework.templates.pickle_utils import dump_obj
  from greykite.framework.templates.pickle_utils import load_obj
  from greykite.framework.templates.simple_silverkite_template import SimpleSilverkiteTemplate
  from greykite.framework.templates.template_interface import TemplateInterface
  from greykite.sklearn.estimator.one_by_one_estimator import OneByOneEstimator
label_desc: Use image node_id 3 for calling the Forecaster obj's underlying member method code with example usage: obj.__get_template_class(config) and returns: template_class