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.
code: def __init_subclass__(cls, validate=True):
      super().__init_subclass__()
      if (
          validate
      ):  # Can be turned off on abstract subclasses or dynamic specs.
          cls._validate()
  
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 1 for calling the ComponentSpec obj's underlying member method code with example usage: obj.__init_subclass__(cls, validate) without return types