class_docstr: Builds a dataflow plan to satisfy a given query.
class_docstr_tok: ["Builds","a","dataflow","plan","to","satisfy","a","given","query","."]
docstr: Return [base_measure_input, conversion_measure_input] for computing a conversion metric.
docstr_tok: ["Return","[","base_measure_input",",","conversion_measure_input","]","for","computing","a","conversion","metric","."]
code: def _build_input_measure_specs_for_conversion_metric(
      self,
      metric_reference: MetricReference,
      conversion_type_params: ConversionTypeParams,
      filter_spec_factory: WhereSpecFactory,
      descendent_filter_specs: Sequence[WhereFilterSpec],
  ) -> Tuple[MetricInputMeasureSpec, MetricInputMeasureSpec]:
      """Return [base_measure_input, conversion_measure_input] for computing a conversion metric."""
      metric = self._metric_lookup.get_metric(metric_reference)
      if metric.type is not MetricType.CONVERSION:
          raise ValueError(
              "This should only be called for conversion metrics."
          )
  
      assert (
          len(metric.input_measures) == 2
      ), f"A conversion metric should exactly 2 measures. Got{metric.input_measures}"
  
      def _get_matching_measure(
          measure_to_match: MeasureReference,
          input_measures: Sequence[MetricInputMeasure],
          is_base_measure: bool,
      ) -> MetricInputMeasureSpec:
          matched_measure = next(
              filter(
                  lambda x: measure_to_match == x.measure_reference,
                  input_measures,
              ),
              None,
          )
          assert (
              matched_measure
          ), f"Unable to find {measure_to_match} in {input_measures}."
          if is_base_measure:
              filter_specs: List[WhereFilterSpec] = []
              filter_specs.extend(
                  filter_spec_factory.create_from_where_filter_intersection(
                      filter_location=WhereFilterLocation.for_metric(
                          metric_reference
                      ),
                      filter_intersection=metric.filter,
                  )
              )
              filter_specs.extend(descendent_filter_specs)
              filter_specs.extend(
                  filter_spec_factory.create_from_where_filter_intersection(
                      filter_location=WhereFilterLocation.for_metric(
                          metric_reference
                      ),
                      filter_intersection=matched_measure.filter,
                  )
              )
          return MetricInputMeasureSpec(
              measure_spec=MeasureSpec.from_name(matched_measure.name),
              fill_nulls_with=matched_measure.fill_nulls_with,
              filter_specs=tuple(filter_specs)
              if is_base_measure
              else (),
              alias=matched_measure.alias,
          )
  
      base_input_measure = _get_matching_measure(
          measure_to_match=conversion_type_params.base_measure.measure_reference,
          input_measures=metric.input_measures,
          is_base_measure=True,
      )
      conversion_input_measure = _get_matching_measure(
          measure_to_match=conversion_type_params.conversion_measure.measure_reference,
          input_measures=metric.input_measures,
          is_base_measure=False,
      )
      return base_input_measure, conversion_input_measure
  
imports: from __future__ import annotations
  import logging
  import time
  from dataclasses import dataclass
  from typing import Dict, List, Optional, Sequence, Set, Tuple, Union
  from dbt_semantic_interfaces.enum_extension import assert_values_exhausted
  from dbt_semantic_interfaces.implementations.metric import PydanticMetricTimeWindow
  from dbt_semantic_interfaces.pretty_print import pformat_big_objects
  from dbt_semantic_interfaces.protocols.metric import ConstantPropertyInput, ConversionTypeParams, MetricInputMeasure, MetricTimeWindow, MetricType
  from dbt_semantic_interfaces.references import MeasureReference, MetricReference, TimeDimensionReference
  from dbt_semantic_interfaces.type_enums.time_granularity import TimeGranularity
  from dbt_semantic_interfaces.validations.unique_valid_name import MetricFlowReservedKeywords
  from metricflow.dag.id_generation import DATAFLOW_PLAN_PREFIX, IdGeneratorRegistry
  from metricflow.dataflow.builder.node_data_set import DataflowPlanNodeOutputDataSetResolver
  from metricflow.dataflow.builder.node_evaluator import JoinLinkableInstancesRecipe, LinkableInstanceSatisfiabilityEvaluation, NodeEvaluatorForLinkableInstances
  from metricflow.dataflow.dataflow_plan import AddGeneratedUuidColumnNode, AggregateMeasuresNode, BaseOutput, CombineAggregatedOutputsNode, ComputeMetricsNode, ConstrainTimeRangeNode, DataflowPlan, FilterElementsNode, JoinConversionEventsNode, JoinDescription, JoinOverTimeRangeNode, JoinToBaseOutputNode, JoinToTimeSpineNode, MinMaxNode, OrderByLimitNode, ReadSqlSourceNode, SemiAdditiveJoinNode, SinkOutput, WhereConstraintNode, WriteToResultDataframeNode, WriteToResultTableNode
  from metricflow.dataflow.dataflow_plan_to_text import dataflow_dag_as_text
  from metricflow.dataflow.optimizer.dataflow_plan_optimizer import DataflowPlanOptimizer
  from metricflow.dataflow.sql_table import SqlTable
  from metricflow.dataset.dataset import DataSet
  from metricflow.errors.errors import UnableToSatisfyQueryError
  from metricflow.filters.time_constraint import TimeRangeConstraint
  from metricflow.mf_logging.pretty_print import mf_pformat
  from metricflow.mf_logging.runtime import log_runtime
  from metricflow.model.semantic_manifest_lookup import SemanticManifestLookup
  from metricflow.plan_conversion.column_resolver import DunderColumnAssociationResolver
  from metricflow.plan_conversion.node_processor import PreJoinNodeProcessor
  from metricflow.query.group_by_item.filter_spec_resolution.filter_location import WhereFilterLocation
  from metricflow.query.group_by_item.filter_spec_resolution.filter_spec_lookup import FilterSpecResolutionLookUp
  from metricflow.specs.column_assoc import ColumnAssociationResolver
  from metricflow.specs.specs import ConstantPropertySpec, CumulativeMeasureDescription, EntitySpec, InstanceSpecSet, JoinToTimeSpineDescription, LinkableInstanceSpec, LinkableSpecSet, LinklessEntitySpec, MeasureSpec, MetadataSpec, MetricFlowQuerySpec, MetricInputMeasureSpec, MetricSpec, NonAdditiveDimensionSpec, OrderBySpec, TimeDimensionSpec, WhereFilterSpec
  from metricflow.specs.where_filter_transform import WhereSpecFactory
  from metricflow.sql.sql_plan import SqlJoinType
label_desc: Use image node_id 22 for calling the DataflowPlanBuilder obj's underlying member method code with example usage: obj._build_input_measure_specs_for_conversion_metric(metric_reference, conversion_type_params, filter_spec_factory, descendent_filter_specs) and returns: base_input_measure,  conversion_input_measure, MetricInputMeasureSpec