class_docstr: A specification of inputs, outputs, parameters, annotation for a component.
  
  Components should have a corresponding ComponentSpec inheriting from this
  class and must override:
  
    - PARAMETERS (as a dict of string keys and ExecutionParameter values),
    - INPUTS (as a dict of string keys and ChannelParameter values),
    - OUTPUTS (also a dict of string keys and ChannelParameter values) and
    - TYPE_ANNOTATION (execution annotations from
    tfx.v1.dsl.standard_annotations)
  
  Here is an example of how a ComponentSpec may be defined:
  
  ```python
  from tfx import v1 as tfx
  
  class MyCustomComponentSpec(ComponentSpec):
    PARAMETERS = {
        'internal_option': ExecutionParameter(type=str),
    }
    INPUTS = {
        'input_examples': ChannelParameter(type=standard_artifacts.Examples),
    }
    OUTPUTS = {
        'output_examples': ChannelParameter(type=standard_artifacts.Examples),
    }
    TYPE_ANNOTATION = tfx.dsl.standard_annotations.Train
  ```
  
  To create an instance of a subclass, call it directly with any execution
  parameters / inputs / outputs as kwargs.  For example:
  
  spec = MyCustomComponentSpec(
      internal_option='abc',
      input_examples=input_examples_channel,
      output_examples=output_examples_channel)
  
  Attributes:
    PARAMETERS: a dict of string keys and ExecutionParameter values.
    INPUTS: a dict of string keys and ChannelParameter values.
    OUTPUTS: a dict of string keys and ChannelParameter values.
    TYPE_ANNOTATION: an execution annotations from
      tfx.v1.dsl.standard_annotations.
docstr: Parse arguments to ComponentSpec.
code: def _parse_parameters(self, raw_args: Mapping[str, Any]):
      """Parse arguments to ComponentSpec."""
      unparsed_args = set(raw_args.keys())
      inputs = {}
      outputs = {}
      self.exec_properties = {}
  
      # First, check that the arguments are set.
      for arg_name, arg in itertools.chain(
          self.PARAMETERS.items(),
          self.INPUTS.items(),
          self.OUTPUTS.items(),
      ):
          if arg_name not in unparsed_args:
              if arg.optional:
                  continue
              else:
                  raise ValueError(
                      "Missing argument %r to %s."
                      % (arg_name, self.__class__)
                  )
          unparsed_args.remove(arg_name)
  
          # Type check the argument.
          value = raw_args[arg_name]
          if arg.optional and value is None:
              continue
          arg.type_check(arg_name, value)
  
      # Populate the appropriate dictionary for each parameter type.
      for arg_name, arg in self.PARAMETERS.items():
          if arg.optional and arg_name not in raw_args:
              continue
          value = raw_args[arg_name]
  
          if (
              inspect.isclass(arg.type)
              and issubclass(
                  arg.type, message.Message
              )  # pytype: disable=not-supported-yet
              and value
              and not _is_runtime_param(value)
          ) and not isinstance(value, placeholder.Placeholder):
              if arg.use_proto:
                  if isinstance(value, dict):
                      value = proto_utils.dict_to_proto(
                          value, arg.type()
                      )
                  elif isinstance(value, str):
                      value = proto_utils.json_to_proto(
                          value, arg.type()
                      )
              else:
                  # Create deterministic json string as it will be stored in metadata
                  # for cache check.
                  if isinstance(value, dict):
                      value = json_utils.dumps(value)
                  elif not isinstance(value, str):
                      value = proto_utils.proto_to_json(value)
  
          self.exec_properties[arg_name] = value
  
      for arg_dict, param_dict in (
          (self.INPUTS, inputs),
          (self.OUTPUTS, outputs),
      ):
          for arg_name, arg in arg_dict.items():
              if arg.optional and not raw_args.get(arg_name):
                  continue
              value = raw_args[arg_name]
              param_dict[arg_name] = value
  
      self.inputs = inputs
      self.outputs = outputs
  
imports: import copy
  import inspect
  import itertools
  from typing import Any, Dict, List, Mapping, Optional, Type, cast
  from tfx.dsl.component.experimental.json_compat import check_strict_json_compat
  from tfx.dsl.placeholder import placeholder
  from tfx.types import artifact
  from tfx.types import channel
  from tfx.types.system_executions import SystemExecution
  from tfx.utils import json_utils
  from tfx.utils import proto_utils
  from google.protobuf import message
label_desc: Use image node_id 5 for calling the ComponentSpec obj's underlying member method code with example usage: obj._parse_parameters(raw_args) without return types