code: def get_valid_artifacts(
      artifacts: Sequence[types.Artifact],
      property_types: Dict[str, types.artifact.PropertyType],
  ) -> List[types.Artifact]:
      """Returns artifacts that have the required property names and types."""
  
      valid_artifacts = []
      for artifact in artifacts:
          if artifact.PROPERTIES is None:
              continue
  
          for property_name, property_type in property_types.items():
              if (
                  property_name not in artifact.PROPERTIES
                  or artifact.PROPERTIES[property_name].type
                  != property_type
              ):
                  break
          else:
              valid_artifacts.append(artifact)
  
      return valid_artifacts
  
file_path: tfx/tfx/dsl/input_resolution/ops/ops_utils.py
imports: from typing import Dict, List, Optional, Sequence, Set
  from tfx import types
  from tfx.orchestration.portable.input_resolution import exceptions
  from tfx.orchestration.portable.mlmd import filter_query_builder
  from tfx.utils import typing_utils
  from ml_metadata.proto import metadata_store_pb2
label_desc: Use image node_id 4 for calling a global function with example usage: get_valid_artifacts(artifacts, property_types) and returns: valid_artifacts