code: def schema_from_feature_spec(
      feature_spec: Mapping[str, common_types.FeatureSpecType],
      domains: Optional[Mapping[str, common_types.DomainType]] = None,
  ) -> schema_pb2.Schema:
      """Convert a feature spec to a Schema proto.
  
      Args:
        feature_spec: A TensorFlow feature spec
        domains: (optional) a dict whose keys are feature names and values are one
          of schema_pb2.IntDomain, schema_pb2.StringDomain or
          schema_pb2.FloatDomain.
  
      Returns:
        A Schema proto
  
      Raises:
        ValueError: If the feature spec cannot be converted to a Schema proto.
      """
      if domains is None:
          domains = {}
  
      result = schema_pb2.Schema()
  
      # Some feature specs can only be represented with the legacy schema, in
      # particular feature specs where any FixedLenFeature has default_value set.
      # We represent these (and only these) using a schema with
      # generate_legacy_feature_spec=True.  Note the generate_legacy_feature_spec
      # field is not part of the open source codebase.
      if schema_utils_legacy.should_set_generate_legacy_feature_spec(
          feature_spec
      ):
          return _legacy_schema_from_feature_spec(feature_spec, domains)
  
      schema_utils_legacy.set_generate_legacy_feature_spec(
          result, False
      )
  
      # Add the features to the schema.
      for name, spec in sorted(feature_spec.items()):
          if isinstance(spec, tf.io.SparseFeature):
              (
                  index_feature,
                  value_feature,
                  sparse_feature,
              ) = _sparse_feature_from_feature_spec(spec, name, domains)
              for f in index_feature:
                  result.feature.add().CopyFrom(f)
              result.feature.add().CopyFrom(value_feature)
              result.sparse_feature.add().CopyFrom(sparse_feature)
  
          elif isinstance(spec, tf.io.RaggedFeature):
              (
                  value_feature,
                  partitions_features,
                  ragged_tensor_representation,
              ) = _ragged_tensor_representation_from_feature_spec(
                  spec, name, domains
              )
              result.feature.add().CopyFrom(value_feature)
              for f in partitions_features:
                  result.feature.add().CopyFrom(f)
              tensor_representation_map = (
                  result.tensor_representation_group[
                      TENSOR_REPRESENTATION_GROUP
                  ].tensor_representation
              )
              tensor_representation_map[name].CopyFrom(
                  ragged_tensor_representation
              )
  
          else:
              result.feature.add().CopyFrom(
                  _feature_from_feature_spec(spec, name, domains)
              )
      return result
  
imports: import dataclasses
  import typing
  from typing import Dict, List, Mapping, Optional, Tuple, Union
  import tensorflow
  from tensorflow_transform import common_types
  from tensorflow_transform.tf_metadata import schema_utils_legacy
  from tfx_bsl.tfxio import tensor_representation_util
  from tensorflow_metadata.proto.v0 import path_pb2
  from tensorflow_metadata.proto.v0 import schema_pb2
label_desc: Use image node_id 1 for calling a global function with example usage: schema_from_feature_spec(feature_spec, domains) and returns: result, _legacy_schema_from_feature_spec