# Path: model_card_toolkit/model_card.py
# class Owner(BaseModelCardField):
# class Version(BaseModelCardField):
# class License(BaseModelCardField):
# class Reference(BaseModelCardField):
# class Citation(BaseModelCardField):
# class ModelDetails(BaseModelCardField):
# class Graphic(BaseModelCardField):
# class GraphicsCollection(BaseModelCardField):
# class SensitiveData(BaseModelCardField):
# class Dataset(BaseModelCardField):
# class KeyVal(BaseModelCardField):
# class ModelParameters(BaseModelCardField):
# class ConfidenceInterval(BaseModelCardField):
# class PerformanceMetric(BaseModelCardField):
# class QuantitativeAnalysis(BaseModelCardField):
# class User(BaseModelCardField):
# class UseCase(BaseModelCardField):
# class Limitation(BaseModelCardField):
# class Tradeoff(BaseModelCardField):
# class Risk(BaseModelCardField):
# class Considerations(BaseModelCardField):
# class ModelCard(BaseModelCardField):
#   def to_json(self) -> str:
#   def from_json(self, json_dict: Dict[str, Any]) -> None:
#   def merge_from_json(self, json: Union[Dict[str, Any], str]) -> None:


import enum
import os
import attr
import tensorflow as tf
import tensorflow_model_analysis as tfma
import ml_metadata as mlmd
from typing import Any, Dict, Iterable, List, Optional, Sequence, Union
from absl import logging
from model_card_toolkit import model_card as model_card_module
from ml_metadata.proto import metadata_store_pb2
from tensorflow_metadata.proto.v0 import statistics_pb2
def _property_value(
    node: Union[metadata_store_pb2.Artifact, metadata_store_pb2.Execution,
                metadata_store_pb2.Context],
    name: str,
    is_custom_property: bool = False) -> Optional[Union[int, float, str]]:
  """Given a MLMD node and a (custom) property name, returns its value if any.

  Args:
    node: A node in MLMD lineage graph. It is one of MLMD Artifact, Execution,
      or Context.
    name: The key of the properties or custom properties.
    is_custom_property: Indicates whether the name is a custom property.

  Returns:
    The value of the property if found in the node; If not, returns None.
  """
  properties = node.custom_properties if is_custom_property else node.properties
  if name not in properties:
    return None
  if properties[name].WhichOneof('value') == 'int_value':
    return properties[name].int_value
  if properties[name].WhichOneof('value') == 'float_value':
    return properties[name].double_value
  return properties[name].string_value


def generate_model_card_for_model(
    store: mlmd.MetadataStore,
    model_id: int,
    pipeline_types: Optional[PipelineTypes] = None

# Path: model_card_toolkit/model_card.py
# class Owner(BaseModelCardField):
# class Version(BaseModelCardField):
# class License(BaseModelCardField):
# class Reference(BaseModelCardField):
# class Citation(BaseModelCardField):
# class ModelDetails(BaseModelCardField):
# class Graphic(BaseModelCardField):
# class GraphicsCollection(BaseModelCardField):
# class SensitiveData(BaseModelCardField):
# class Dataset(BaseModelCardField):
# class KeyVal(BaseModelCardField):
# class ModelParameters(BaseModelCardField):
# class ConfidenceInterval(BaseModelCardField):
# class PerformanceMetric(BaseModelCardField):
# class QuantitativeAnalysis(BaseModelCardField):
# class User(BaseModelCardField):
# class UseCase(BaseModelCardField):
# class Limitation(BaseModelCardField):
# class Tradeoff(BaseModelCardField):
# class Risk(BaseModelCardField):
# class Considerations(BaseModelCardField):
# class ModelCard(BaseModelCardField):
#   def to_json(self) -> str:
#   def from_json(self, json_dict: Dict[str, Any]) -> None:
#   def merge_from_json(self, json: Union[Dict[str, Any], str]) -> None:


# Path: model_card_toolkit/utils/tfx_util.py
import enum
import os
import attr
import tensorflow as tf
import tensorflow_model_analysis as tfma
import ml_metadata as mlmd
from typing import Any, Dict, Iterable, List, Optional, Sequence, Union
from absl import logging
from model_card_toolkit import model_card as model_card_module
from ml_metadata.proto import metadata_store_pb2
from tensorflow_metadata.proto.v0 import statistics_pb2

def _property_value(
    node: Union[metadata_store_pb2.Artifact, metadata_store_pb2.Execution,
                metadata_store_pb2.Context],
    name: str,
    is_custom_property: bool = False) -> Optional[Union[int, float, str]]:
  """Given a MLMD node and a (custom) property name, returns its value if any.

  Args:
    node: A node in MLMD lineage graph. It is one of MLMD Artifact, Execution,
      or Context.
    name: The key of the properties or custom properties.
    is_custom_property: Indicates whether the name is a custom property.

  Returns:
    The value of the property if found in the node; If not, returns None.
  """
  properties = node.custom_properties if is_custom_property else node.properties
  if name not in properties:
    return None
  if properties[name].WhichOneof('value') == 'int_value':
    return properties[name].int_value
  if properties[name].WhichOneof('value') == 'float_value':
    return properties[name].double_value
  return properties[name].string_value


def generate_model_card_for_model(
    store: mlmd.MetadataStore,
    model_id: int,
    pipeline_types: Optional[PipelineTypes] = None

) -> model_card_module.ModelCard: