class_docstr: Rule engine to processes rules
class_docstr_tok: ["Rule","engine","to","processes","rules"]
docstr: Assigns publishers to each output.
  
  The @Rule publisher syntax accepts several formats, including a more permissive blanket
  option.
  
  In this configuration we DELIBERATELY do not include required_outputs as required outputs
  should never have their alerts transformed.
  
  Args:
      rule (Rule): The rule to create publishers for
      requested_outputs (set): A set containing the outputs
  
  Returns:
      dict: Maps string outputs names to lists of strings of their fully qualified publishers
docstr_tok: ["Assigns","publishers","to","each","output",".","The","@","Rule","publisher","syntax","accepts","several","formats",",","including","a","more","permissive","blanket","option",".","In","this","configuration","we","DELIBERATELY","do","not","include","required_outputs","as","required","outputs","should","never","have","their","alerts","transformed",".","Args",":","rule","(","Rule",")",":","The","rule","to","create","publishers","for","requested_outputs","(","set",")",":","A","set","containing","the","outputs","Returns",":","dict",":","Maps","string","outputs","names","to","lists","of","strings","of","their","fully","qualified","publishers"]
code: def _configure_publishers(cls, rule, requested_outputs):
      """Assigns publishers to each output.
  
      The @Rule publisher syntax accepts several formats, including a more permissive blanket
      option.
  
      In this configuration we DELIBERATELY do not include required_outputs as required outputs
      should never have their alerts transformed.
  
      Args:
          rule (Rule): The rule to create publishers for
          requested_outputs (set): A set containing the outputs
  
      Returns:
          dict: Maps string outputs names to lists of strings of their fully qualified publishers
      """
      requested_publishers = rule.publishers
      if not requested_publishers:
          return None
  
      configured_publishers = {}
  
      for output in requested_outputs:
          if output == "aws-firehose:alerts":
              # This output doesn't require a publisher
              continue
  
          assigned_publishers = []
  
          if cls.is_publisher_declaration(requested_publishers):
              # Case 1: The publisher is a single string.
              #   apply this single publisher to all outputs + descriptors
              cls.add_publisher(
                  requested_publishers, assigned_publishers
              )
          elif isinstance(requested_publishers, list):
              # Case 2: The publisher is an array of strings.
              #   apply all publishers to all outputs + descriptors
              cls.add_publishers(
                  requested_publishers, assigned_publishers
              )
          elif isinstance(requested_publishers, dict):
              # Case 3: The publisher is a dict mapping output strings -> strings or list of
              #   strings. Apply only publishers under a matching output key.
              #
              #   We look under 2 keys:
              #     - [Output]: Applies publishers to all outputs for a specific output type.
              #     - [Output+Descriptor]: Applies publishers only to the specific output that
              #           exactly matches the output+descriptor key.
              output_service = output.split(":")[0]
  
              # Order is important here; We load output-specific publishers first
              if output_service in requested_publishers:
                  specific_publishers = requested_publishers[
                      output_service
                  ]
                  if cls.is_publisher_declaration(specific_publishers):
                      cls.add_publisher(
                          specific_publishers, assigned_publishers
                      )
                  elif isinstance(specific_publishers, list):
                      cls.add_publishers(
                          specific_publishers, assigned_publishers
                      )
  
              # Then we load the output+descriptor-specific publishers second
              if output in requested_publishers:
                  specific_publishers = requested_publishers[output]
                  if cls.is_publisher_declaration(specific_publishers):
                      cls.add_publisher(
                          specific_publishers, assigned_publishers
                      )
                  elif isinstance(specific_publishers, list):
                      cls.add_publishers(
                          specific_publishers, assigned_publishers
                      )
          else:
              LOGGER.error(
                  "Invalid publisher argument: %s", requested_publishers
              )
  
          configured_publishers[output] = assigned_publishers
  
      return configured_publishers
  
imports: from datetime import datetime, timedelta
  from os import environ
  from streamalert.shared.publisher import AlertPublisherRepository
  from streamalert.rules_engine.alert_forwarder import AlertForwarder
  from streamalert.rules_engine.threat_intel import ThreatIntel
  from streamalert.shared import resources, RULES_ENGINE_FUNCTION_NAME
  from streamalert.shared.alert import Alert
  from streamalert.shared.config import load_config
  from streamalert.shared.importer import import_folders
  from streamalert.shared.logger import get_logger
  from streamalert.shared.lookup_tables.core import LookupTables
  from streamalert.shared.metrics import MetricLogger
  from streamalert.shared.rule import Rule
  from streamalert.shared.rule_table import RuleTable
  from streamalert.shared.stats import RuleStatisticTracker
label_desc: Use image node_id 12 for calling the RulesEngine obj's underlying member method code with example usage: obj._configure_publishers(cls, rule, requested_outputs) and returns: configured_publishers, None