99from typing import Any , Callable , Dict , List , Optional , Set , Tuple , TypedDict , Union , cast
1010
1111from azure .ai .evaluation ._legacy ._adapters ._constants import LINE_NUMBER
12+ from azure .ai .evaluation ._legacy ._adapters ._errors import MissingRequiredPackage
1213from azure .ai .evaluation ._legacy ._adapters .entities import Run
1314import pandas as pd
1415
4041 _write_output ,
4142 DataLoaderFactory ,
4243)
43- from ._batch_run .batch_clients import BatchClient
44+ from ._batch_run .batch_clients import BatchClient , BatchClientRun
4445
4546LOGGER = logging .getLogger (__name__ )
4647
@@ -486,12 +487,12 @@ def _validate_and_load_data(target, data, evaluators, output_path, azure_ai_proj
486487
487488def _apply_target_to_data (
488489 target : Callable ,
489- data : Union [str , os .PathLike ],
490+ data : Union [str , os .PathLike , pd . DataFrame ],
490491 batch_client : BatchClient ,
491492 initial_data : pd .DataFrame ,
492493 evaluation_name : Optional [str ] = None ,
493494 ** kwargs ,
494- ) -> Tuple [pd .DataFrame , Set [str ], Run ]:
495+ ) -> Tuple [pd .DataFrame , Set [str ], BatchClientRun ]:
495496 """
496497 Apply the target function to the data set and return updated data and generated columns.
497498
@@ -509,24 +510,18 @@ def _apply_target_to_data(
509510 :rtype: Tuple[pandas.DataFrame, List[str]]
510511 """
511512
512- if not isinstance (batch_client , ProxyClient ):
513- raise ValueError ("Only ProxyClient supports target runs for now." )
514-
515513 _run_name = kwargs .get ("_run_name" )
516- with TargetRunContext ():
517- run = cast (
518- ProxyRun ,
519- batch_client .run (
520- flow = target ,
521- display_name = evaluation_name ,
522- data = data ,
523- stream = True ,
524- name = _run_name ,
525- ),
514+ with TargetRunContext (batch_client ):
515+ run : BatchClientRun = batch_client .run (
516+ flow = target ,
517+ display_name = evaluation_name ,
518+ data = data ,
519+ stream = True ,
520+ name = _run_name ,
521+ evaluator_name = getattr (target , "__qualname__" , "TARGET" ),
526522 )
527-
528- target_output : pd .DataFrame = batch_client .get_details (run , all_results = True )
529- run_summary = batch_client .get_run_summary (run )
523+ target_output : pd .DataFrame = batch_client .get_details (run , all_results = True )
524+ run_summary = batch_client .get_run_summary (run )
530525
531526 if run_summary ["completed_lines" ] == 0 :
532527 msg = (
@@ -557,7 +552,7 @@ def _apply_target_to_data(
557552 # Concatenate output to input
558553 target_output = pd .concat ([target_output , initial_data ], axis = 1 )
559554
560- return target_output , generated_columns , run . run . result ()
555+ return target_output , generated_columns , run
561556
562557
563558def _process_column_mappings (
@@ -777,19 +772,27 @@ def _evaluate( # pylint: disable=too-many-locals,too-many-statements
777772 column_mapping = column_mapping or {}
778773 column_mapping .setdefault ("default" , {})
779774
780- target_run : Optional [Run ] = None
775+ target_run : Optional [BatchClientRun ] = None
781776 target_generated_columns : Set [str ] = set ()
782777 batch_run_client : BatchClient
783778 batch_run_data : Union [str , os .PathLike , pd .DataFrame ] = data
784779
785- # If target is set, apply 1-1 column mapping from target outputs to evaluator inputs
786- if data is not None and target is not None :
787- # Right now, only the ProxyClient that uses Promptflow supports a target function
780+ if kwargs .pop ("_use_run_submitter_client" , False ):
781+ batch_run_client = RunSubmitterClient ()
782+ batch_run_data = input_data_df
783+ elif kwargs .pop ("_use_pf_client" , True ):
788784 batch_run_client = ProxyClient (user_agent = USER_AGENT )
785+ # Ensure the absolute path is passed to pf.run, as relative path doesn't work with
786+ # multiple evaluators. If the path is already absolute, abspath will return the original path.
789787 batch_run_data = os .path .abspath (data )
788+ else :
789+ batch_run_client = CodeClient ()
790+ batch_run_data = input_data_df
790791
792+ # If target is set, apply 1-1 column mapping from target outputs to evaluator inputs
793+ if data is not None and target is not None :
791794 input_data_df , target_generated_columns , target_run = _apply_target_to_data (
792- target , data , batch_run_client , input_data_df , evaluation_name , ** kwargs
795+ target , batch_run_data , batch_run_client , input_data_df , evaluation_name , ** kwargs
793796 )
794797
795798 for evaluator_name , mapping in column_mapping .items ():
@@ -803,17 +806,6 @@ def _evaluate( # pylint: disable=too-many-locals,too-many-statements
803806 # customer did not mapped target output.
804807 if col not in mapping and run_output not in mapped_to_values :
805808 column_mapping [evaluator_name ][col ] = run_output # pylint: disable=unnecessary-dict-index-lookup
806- elif kwargs .pop ("_use_run_submitter_client" , False ):
807- batch_run_client = RunSubmitterClient ()
808- batch_run_data = input_data_df
809- elif kwargs .pop ("_use_pf_client" , True ):
810- batch_run_client = ProxyClient (user_agent = USER_AGENT )
811- # Ensure the absolute path is passed to pf.run, as relative path doesn't work with
812- # multiple evaluators. If the path is already absolute, abspath will return the original path.
813- batch_run_data = os .path .abspath (data )
814- else :
815- batch_run_client = CodeClient ()
816- batch_run_data = input_data_df
817809
818810 # After we have generated all columns, we can check if we have everything we need for evaluators.
819811 _validate_columns_for_evaluators (input_data_df , evaluators , target , target_generated_columns , column_mapping )
@@ -896,12 +888,11 @@ def _evaluate( # pylint: disable=too-many-locals,too-many-statements
896888 metrics .update (evaluators_metric )
897889
898890 # Since tracing is disabled, pass None for target_run so a dummy evaluation run will be created each time.
899- target_run : Optional [Run ] = None
900891 trace_destination = _trace_destination_from_project_scope (azure_ai_project ) if azure_ai_project else None
901892 studio_url = None
902893 if trace_destination :
903894 studio_url = _log_metrics_and_instance_results (
904- metrics , result_df , trace_destination , target_run , evaluation_name , ** kwargs
895+ metrics , result_df , trace_destination , None , evaluation_name , ** kwargs
905896 )
906897
907898 result_df_dict = result_df .to_dict ("records" )
0 commit comments