Repository: microsoft/promptflow
File: src/promptflow-evals/promptflow/evals/evaluate/_evaluate.py (Python)

Code before:
    :paramtype data: str
    :keyword pf_client: The promptflow client to be used.
    :paramtype pf_client: PFClient
    :return: The path to data file with answers from target function.
    :rtype: str
    """
    # We are manually creating the temporary directory for the flow
    # because the way tempdir remove temporary directories will
    # hang the debugger, because promptflow will keep flow directory.
    saved_flow = f'flow_{uuid.uuid1()}'
    os.makedirs(saved_flow)
    save_function_as_flow(fun=target, target_dir=saved_flow, pf=pf_client)
    run = pf_client.run(
        flow=saved_flow,
        data=data,
        name=f'preprocess_{uuid.uuid1()}'
    )
    run = pf_client.stream(run)
    # Delete temporary directory if we can.
    try:
        shutil.rmtree(saved_flow)
    except BaseException:
        # Exception means, we are running in debugger. In this case we can keep the
        # directory.
        pass
    function_output = pd.read_json(pf_client.runs._get_outputs_path(run),
                                   orient='records', lines=True)
    function_output.set_index(LINE_NUMBER, inplace=True)
    function_output.sort_index(inplace=True)
    data_input = pd.read_json(data, orient='records', lines=True)
    data_input = pd.concat([data_input, function_output], axis=1, verify_integrity=True)
    del function_output
    new_data_name = f'{uuid.uuid1()}.jsonl'
    data_input.to_json(new_data_name, orient='records', lines=True)
    return new_data_name


def evaluate(
    *,
    evaluation_name: Optional[str] = None,
    target: Optional[Callable] = None,
    data: Optional[str] = None,
    evaluators: Optional[Dict[str, Callable]] = None,
    evaluator_config: Optional[Dict[str, Dict[str, str]]] = {},
    tracking_uri: Optional[str] = None,
    output_path: Optional[str] = None,
    **kwargs,
):
    """Evaluates target or data with built-in evaluation metrics

    :keyword evaluation_name: Display name of the evaluation.

Review comment (suggestion):
There is a pf api to get output as dataframe. Should we use it directly ? I think its called `get_results`

Code after:
        stream=True
    )
    target_output = pf_client.runs.get_details(run, all_results=True)
    # Remove input and output prefix
    prefix = 'outputs.'
    rename_dict = {col: col[len(prefix):] for col in target_output.columns if col.startswith(prefix)}
    # Sort output by line numbers
    target_output.set_index(f'inputs.{LINE_NUMBER}', inplace=True)
    target_output.sort_index(inplace=True)
    target_output.reset_index(inplace=True, drop=False)
    # target_output contains only input columns, taken by function,
    # so we need to concatenate it to the input data frame.
    drop_columns = set(target_output.columns) - set(rename_dict.keys())
    target_output.drop(drop_columns, inplace=True, axis=1)
    # Remove outputs. prefix
    target_output.rename(columns=rename_dict, inplace=True)
    # Concatenate output to input
    target_output = pd.concat([target_output, initial_data], axis=1)
    return target_output, set(rename_dict.values())


def evaluate(
    *,
    evaluation_name: Optional[str] = None,
    target: Optional[Callable] = None,
    data: Optional[str] = None,
    evaluators: Optional[Dict[str, Callable]] = None,
    evaluator_config: Optional[Dict[str, Dict[str, str]]] = {},
    tracking_uri: Optional[str] = None,
    output_path: Optional[str] = None,
    **kwargs,
):
    """Evaluates target or data with built-in evaluation metrics

    :keyword evaluation_name: Display name of the evaluation.
    :paramtype evaluation_name: Optional[str]
    :keyword target: Target to be evaluated. `target` and `data` both cannot be None
    :paramtype target: Optional[Callable]
    :keyword data: Path to the data to be evaluated or passed to target if target is set.
        Only .jsonl format files are supported.  `target` and `data` both cannot be None
    :paramtype data: Optional[str]
    :keyword evaluator_config: Configuration for evaluators.
    :paramtype evaluator_config: Optional[Dict[str, Dict[str, str]]
    :keyword output_path: The local folder path to save evaluation artifacts to if set
    :paramtype output_path: Optional[str]
    :keyword tracking_uri: Tracking uri to log evaluation results to AI Studio
    :paramtype tracking_uri: Optional[str]
    :return: A EvaluationResult object.
    :rtype: ~azure.ai.generative.evaluate.EvaluationResult
    """