class_docstr: Centralized config for handling configuration loading/parsing
class_docstr_tok: ["Centralized","config","for","handling","configuration","loading\/parsing"]
docstr: Validate the top level of the config to make sure it has all the right keys
  
  Raises:
      AppConfigError: If the config is invalid, this exception is raised
docstr_tok: ["Validate","the","top","level","of","the","config","to","make","sure","it","has","all","the","right","keys","Raises",":","AppConfigError",":","If","the","config","is","invalid",",","this","exception","is","raised"]
code: def _validate_event(cls, event):
      """Validate the top level of the config to make sure it has all the right keys
  
      Raises:
          AppConfigError: If the config is invalid, this exception is raised
      """
      event_key_diff = cls.required_event_keys().difference(set(event))
      if not event_key_diff:
          return
  
      missing_event_keys = ", ".join(
          "'{}'".format(key) for key in event_key_diff
      )
      raise AppConfigError(
          "App event is missing the following required "
          "keys: {}".format(missing_event_keys)
      )
  
imports: import calendar
  from datetime import datetime
  import json
  import re
  import time
  import backoff
  import boto3
  from botocore import client
  from botocore.exceptions import ClientError
  from streamalert.apps.exceptions import AppAuthError, AppConfigError, AppStateError
  from streamalert.shared.logger import get_logger
label_desc: Use image node_id 17 for calling the AppConfig obj's underlying member method code with example usage: obj._validate_event(cls, event) without return types