class_docstr: Abstract Parser class to be inherited by all StreamAlert Parsers
class_docstr_tok: ["Abstract","Parser","class","to","be","inherited","by","all","StreamAlert","Parsers"]
docstr: Main parser method to be handle parsing of the passed data
  
  Args:
      data (str|dict): Data to be parsed.
  
  Returns:
      bool: True if any records were parsed using this schema, False otherwise
docstr_tok: ["Main","parser","method","to","be","handle","parsing","of","the","passed","data","Args",":","data","(","str|dict",")",":","Data","to","be","parsed",".","Returns",":","bool",":","True","if","any","records","were","parsed","using","this","schema",",","False","otherwise"]
code: def parse(self, data):
      """Main parser method to be handle parsing of the passed data
  
      Args:
          data (str|dict): Data to be parsed.
  
      Returns:
          bool: True if any records were parsed using this schema, False otherwise
      """
      # Ensure the schema is defined properly. Invalid schemas will not be used
      if not self._validate_schema():
          LOGGER.error(
              "Schema definition is not valid (%s):\n%s",
              self._schema_type,
              self._schema,
          )
          return False
  
      data_copy = None
      # If the data is a mutable object, copy it since
      # the parse(s) can highly mutate the input
      if isinstance(data, dict):
          data_copy = deepcopy(data)
  
      # If the data is a string, attempt to load it to json,
      # falling back on a string type on error
      elif isinstance(data, (str, bytes)):
          try:
              data_copy = json.loads(data)
          except (ValueError, TypeError) as err:
              LOGGER.debug("Data is not valid json: %s", err)
              data_copy = data
  
      # Check to make sure any non-optional envelope keys exist before proceeding
      if not self._key_check(
          data_copy,
          self._envelope_schema,
          self._optional_envelope_keys,
          True,
      ):
          return False
  
      # Get the envelope and try to convert the value to the proper type(s)
      envelope = self._extract_envelope(data_copy)
      if not self._convert_type(
          envelope, self._envelope_schema, self._optional_envelope_keys
      ):
          return False
  
      # Add the optional envelope keys to record once at the beginning
      self._add_optional_keys(
          envelope, self._envelope_schema, self._optional_envelope_keys
      )
  
      for record, valid in self._parse(data_copy):
          valid = valid and self._key_check(
              record, self._schema, self._optional_top_level_keys
          )
          valid = valid and self._convert_type(
              record, self._schema, self._optional_top_level_keys
          )
          valid = valid and self._matches_log_patterns(
              record, self._log_patterns, envelope
          )
          self._add_parse_result(record, valid, envelope)
  
      return self.valid
  
imports: from abc import ABCMeta, abstractmethod
  from copy import deepcopy
  import csv
  from fnmatch import fnmatch
  import json
  import logging
  import re
  import io
  import jmespath
  from streamalert.shared.logger import get_logger
label_desc: Use image node_id 26 for calling the ParserBase obj's underlying member method code with example usage: obj.parse(data) and returns: self, False, False, False