o
    /ifQ                     @   s(  d dl mZmZmZ d dlmZmZ d dlmZ d dl	m
Z
mZmZ d dlZd dlZd dlZd dlZd dlZd dlZd dlmZ d dlmZmZ d dlmZmZmZ d d	lmZmZmZ d d
l m!Z!m"Z" d dl#m$Z$m%Z% d dl&m'Z' d dl(m)Z) ddgZ*dee$e%f de+fddZ,eG dd dZ-dS )    )ListOptionalUnion)	dataclassfield)Console)ProgressSpinnerColumn
TextColumnN)
BaseMetric)Api	Endpoints)convert_test_cases_to_goldensconvert_goldens_to_test_cases)convert_convo_goldens_to_convo_test_cases)
APIDatasetCreateDatasetHttpResponseDatasetHttpResponse)GoldenConversationalGolden)LLMTestCaseConversationalTestCase)is_confident)BaseSynthesizercsvjson	test_casesubjectc                 C   s,   t | tst | tstd| dd S d S )Nz
Provided `z9` must be a list of LLMTestCase or ConversationalTestCase)
isinstancer   r   	TypeError)r   r    r    Q/var/www/html/corbot_env/lib/python3.10/site-packages/deepeval/dataset/dataset.pyvalidate_test_case_type    s   
r"   c                   @   sh  e Zd ZU ee ed< ee ed< eddZe	e
df ed< eddZe	e
df ed< eg ddZee ed< eg ddZee ed	< g g g fd
ee	eef  dee dee fddZdd Zedee	eef  fddZejd
ee	eef  fddZde	eef fddZdd Zdee fddZ					dNde
de
de
dee
 d ee
 d!e
d"ee
 d#e
fd$d%Z			dOde
d&e
d'e
d(ee
 d)ee
 d*ee
 fd+d,ZdPd-e
d.ee fd/d0ZdQd-e
d2efd3d4Z		5	6	7		1dRd8eee
  d9ed:e d;e d<ed=eee
  d>efd?d@Z!		A	B	C	6	7dSdDee
 d9edEe dFe dGe d;e d<efdHdIZ"dJe
dKe
de
fdLdMZ#dS )TEvaluationDatasetgoldensconversational_goldensNdefault_alias_id)default_factoryrepr_llm_test_cases_conversational_test_cases
test_casesc                 C   s   |D ]}t |dd q|| _|| _d | _d | _g }g }|D ]!}t|tr/t||_|	| qt|t
r>t||_|	| q|| _|| _d S Nz
test cases)r   )r"   r$   r%   r(   r)   r   r   len_dataset_rankappendr   r,   r-   )selfr.   r$   r%   r   llm_test_casesconversational_test_casesr    r    r!   __init__6   s$   





zEvaluationDataset.__init__c                 C   s6   | j j d| j d| j d| j d| j d| j dS )Nz(test_cases=z
, goldens=z, conversational_goldens=z	, _alias=z, _id=))	__class____name__r.   r$   r%   r(   r)   r3   r    r    r!   __repr__P   s   zEvaluationDataset.__repr__returnc                 C   s   | j | j S N)r,   r-   r:   r    r    r!   r.   X   s   zEvaluationDataset.test_casesc                 C   s   t |ts	tdg }g }|D ]4}t |tst |tsq| j|_| j|_t |tr4t	||_
|| qt |trCt	||_
|| q|| _|| _d S )Nz'test_cases' must be a list)r   listr   r   r   r(   _dataset_aliasr)   _dataset_idr0   r1   r2   r,   r-   )r3   r.   r4   r5   r   r    r    r!   r.   \   s(   






r   c                 C   sl   t |dd | j|_| j|_t|tr!t| j|_	| j
| d S t|tr4t| j|_	| j
| d S d S r/   )r"   r(   r?   r)   r@   r   r   r0   r,   r1   r2   r   r-   )r3   r   r    r    r!   add_test_casew   s   

zEvaluationDataset.add_test_casec                 C   s
   t | jS r=   )iterr.   r:   r    r    r!   __iter__   s   
zEvaluationDataset.__iter__metricsc                 C   s.   ddl m} t| jdkrtd|| j|S )Nr   )evaluatezLNo test cases found in evaluation dataset. Unable to evaluate empty dataset.)deepevalrE   r0   r.   
ValueError)r3   rD   rE   r    r    r!   rE      s   zEvaluationDataset.evaluate;	file_pathinput_col_nameactual_output_col_nameexpected_output_col_namecontext_col_namecontext_col_delimiterretrieval_context_col_nameretrieval_context_col_delimiterc	              
      s   zddl }	W n ty   tdw dd|	jdtfdd}
|	|}|
||}|
||}|
||dd} fd	d
|
||ddD }fdd
|
||ddD }t|||||D ]\}}}}}| t|||||d qWdS )ab  
        Load test cases from a CSV file.

        This method reads a CSV file, extracting test case data based on specified column names. It creates LLMTestCase objects for each row in the CSV and adds them to the Dataset instance. The context data, if provided, is expected to be a delimited string in the CSV, which this method will parse into a list.

        Args:
            file_path (str): Path to the CSV file containing the test cases.
            input_col_name (str): The column name in the CSV corresponding to the input for the test case.
            actual_output_col_name (str): The column name in the CSV corresponding to the actual output for the test case.
            expected_output_col_name (str, optional): The column name in the CSV corresponding to the expected output for the test case. Defaults to None.
            context_col_name (str, optional): The column name in the CSV corresponding to the context for the test case. Defaults to None.
            context_delimiter (str, optional): The delimiter used to separate items in the context list within the CSV file. Defaults to ';'.
            retrieval_context_col_name (str, optional): The column name in the CSV corresponding to the retrieval context for the test case. Defaults to None.
            retrieval_context_delimiter (str, optional): The delimiter used to separate items in the retrieval context list within the CSV file. Defaults to ';'.

        Returns:
            None: The method adds test cases to the Dataset instance but does not return anything.

        Raises:
            FileNotFoundError: If the CSV file specified by `file_path` cannot be found.
            pd.errors.EmptyDataError: If the CSV file is empty.
            KeyError: If one or more specified columns are not found in the CSV file.

        Note:
            The CSV file is expected to contain columns as specified in the arguments. Each row in the file represents a single test case. The method assumes the file is properly formatted and the specified columns exist. For context data represented as lists in the CSV, ensure the correct delimiter is specified.
        r   Nz>Please install pandas to use this method. 'pip install pandas'dfcol_namec                 S   s"   || j v r
| | jS |gt|  S r=   )columnsvaluesr0   )rQ   rR   r'   r    r    r!   get_column_data   s
   
zGEvaluationDataset.add_test_cases_from_csv_file.<locals>.get_column_datar&   c                       g | ]}|r|  ng qS r    split).0context)rN   r    r!   
<listcomp>   s    zBEvaluationDataset.add_test_cases_from_csv_file.<locals>.<listcomp> c                    rV   r    rW   )rY   retreival_context)rP   r    r!   r[      s    inputactual_outputexpected_outputrZ   retrieval_contextr=   )pandasModuleNotFoundError	DataFramestrread_csvziprA   r   )r3   rI   rJ   rK   rL   rM   rN   rO   rP   pdrU   rQ   inputsactual_outputsexpected_outputscontextsretrieval_contextsr_   r`   ra   rZ   rb   r    )rN   rP   r!   add_test_cases_from_csv_file   sZ   %




z.EvaluationDataset.add_test_cases_from_csv_fileinput_key_nameactual_output_key_nameexpected_output_key_namecontext_key_nameretrieval_context_key_namec              
   C   s   zt |d}t|}W d   n1 sw   Y  W n ty+   td| d tjy:   td| dw |D ]1}	||	vsG||	vrKtd|	| }
|	| }|	|}|	|}|	|}| t|
||||d q=dS )a  
        Load test cases from a JSON file.

        This method reads a JSON file containing a list of objects, each representing a test case. It extracts the necessary information based on specified key names and creates LLMTestCase objects to add to the Dataset instance.

        Args:
            file_path (str): Path to the JSON file containing the test cases.
            input_key_name (str): The key name in the JSON objects corresponding to the input for the test case.
            actual_output_key_name (str): The key name in the JSON objects corresponding to the actual output for the test case.
            expected_output_key_name (str, optional): The key name in the JSON objects corresponding to the expected output for the test case. Defaults to None.
            context_key_name (str, optional): The key name in the JSON objects corresponding to the context for the test case. Defaults to None.
            retrieval_context_key_name (str, optional): The key name in the JSON objects corresponding to the retrieval context for the test case. Defaults to None.

        Returns:
            None: The method adds test cases to the Dataset instance but does not return anything.

        Raises:
            FileNotFoundError: If the JSON file specified by `file_path` cannot be found.
            ValueError: If the JSON file is not valid or if required keys (input and actual output) are missing in one or more JSON objects.

        Note:
            The JSON file should be structured as a list of objects, with each object containing the required keys. The method assumes the file format and keys are correctly defined and present.
        rNz	The file z was not found.z is not a valid JSON file.z7Required fields are missing in one or more JSON objectsr^   )	openr   loadFileNotFoundErrorJSONDecodeErrorrG   getrA   r   )r3   rI   rp   rq   rr   rs   rt   file	json_listjson_objr_   r`   ra   rZ   rb   r    r    r!   add_test_cases_from_json_file   s>    


z/EvaluationDataset.add_test_cases_from_json_filealias	overwritec                 C   s   t | jdkrt | jdkrtdt rs| j}|t| j t|||| jd}z	|j	ddd}W n t
yB   |jddd}Y nw t }|jtjj|d}|rqt|d d}|j}	t }
|
d	|	 d
|	 d t|	 d S d S td)Nr   zgUnable to push empty dataset to Confident AI, there must be at least one test case or golden in dataset)r   r   r$   conversationalGoldensT)by_aliasexclude_none)endpointbodylink)r   u?   ✅ Dataset successfully pushed to Confidnet AI! View at [link=]z[/link]z5To push dataset to Confident AI, run `deepeval login`)r0   r.   r$   rG   r   extendr   r   r%   
model_dumpAttributeErrordictr   post_requestr   DATASET_ENDPOINTvaluer   r   r   print
webbrowserrv   	Exception)r3   r   r   r$   api_datasetr   apiresultresponser   consoler    r    r!   push4  sR   zEvaluationDataset.pushT"auto_convert_goldens_to_test_casesc                 C   s4  t  rt }ttddtdddz}|jd| ddd	}t }|jt	j
jd
|id}t|d |d |d d}|| _|j| _|r`t|j||j}	t|j||j}
| j|	 | j|
 n|j| _|j| _t }t|| d}|j||j| j d| dd W d    d S 1 sw   Y  d S td)Nzrgb(106,0,255))stylez([progress.description]{task.description}F)	transientzPulling [rgb(106,0,255)]'z''[/rgb(106,0,255)] from Confident AI...d   )totalr   )r   paramsr$   r   	datasetId)r$   r   r   z.2fz [rgb(25,227,160)]Done! (zs))descriptionz6Run `deepeval login` to pull dataset from Confident AI)r   r   r   r	   r
   add_tasktimeperf_counterget_requestr   r   r   r   r(   r   r)   r   r$   r   r%   r,   r   r-   formatupdatetasksr   r   )r3   r   r   r   progresstask_id
start_timer   r   r4   r5   end_time
time_takenr    r    r!   pull]  sf   

"4zEvaluationDataset.pull      Frm   synthesizermax_goldens_per_contextnum_evolutionsenable_breadth_evolvesource_files_show_indicatorc           	   
   C   <   ddl m} |d u r| }| j|j||||||d d S )Nr   Synthesizer)rm   r   r   r   r   r   )deepeval.synthesizerr   r$   r   generate_goldens)	r3   rm   r   r   r   r   r   r   r   r    r    r!   r        
z"EvaluationDataset.generate_goldens      r   document_pathsmax_goldens_per_document
chunk_sizechunk_overlapc           	   
   C   r   )Nr   r   )r   r   r   r   r   r   )r   r   r$   r   generate_goldens_from_docs)	r3   r   r   r   r   r   r   r   r   r    r    r!   r     r   z,EvaluationDataset.generate_goldens_from_docs	file_type	directoryc           	   
   C   sf  |t vrtdddd t D  t| jdkr!td| tj dd|  }tj	
|s9t| tj	||}|d	krjt|d
}dd | jD }tj||dd W d    n1 sdw   Y  n?|dkrt|d
dd,}t|}|g d | jD ]}||j|j|jd|j|jg qW d    n1 sw   Y  td| d |S )Nz4Invalid file type. Available file types to save as: z, c                 s   s    | ]}|V  qd S r=   r    )rY   typer    r    r!   	<genexpr>  s    z,EvaluationDataset.save_as.<locals>.<genexpr>r   zVNo synthetic goldens found. Please generate goldens before attempting to save data as z%Y%m%d_%H%M%S.r   wc                 S   s&   g | ]}|j |j|j|j|jd qS )r_   r`   ra   rZ   source_filer   )rY   goldenr    r    r!   r[     s    z-EvaluationDataset.save_as.<locals>.<listcomp>   )indentr   r\   )newliner   |zEvaluation dataset saved at !)valid_file_typesrG   joinr0   r$   datetimenowstrftimeospathexistsmakedirsrv   r   dumpr   writerwriterowr_   r`   ra   rZ   r   r   )	r3   r   r   new_filenamefull_file_pathr{   	json_datar   r   r    r    r!   save_as  sP   



	
zEvaluationDataset.save_as)NNrH   NrH   )NNNr=   )T)Nr   r   FNT)Nr   r   r   r   F)$r9   
__module____qualname__r   r   __annotations__r   r   r(   r   rf   r)   r,   r   r-   r   r6   r;   propertyr.   setterrA   rC   r   rE   r   ro   r~   boolr   r   r   intr   r   r   r    r    r    r!   r#   +   s   
 


	
e
B)>



r#   ).typingr   r   r   dataclassesr   r   rich.consoler   rich.progressr   r	   r
   r   r   r   r   r   r   deepeval.metricsr   deepeval.apir   r   deepeval.dataset.utilsr   r   r   deepeval.dataset.apir   r   r   deepeval.dataset.goldenr   r   deepeval.test_caser   r   deepeval.utilsr   %deepeval.synthesizer.base_synthesizerr   r   rf   r"   r#   r    r    r    r!   <module>   s4    

