a
    _g؉                     @  sP  U d dl mZ d dlZd dlZd dlmZmZmZmZm	Z	 d dl
mZ ddlmZ G dd de	Zed	d
dZdddddZddddddZddgfddddddZd^ddddddZddgfddddddZddddd Zdddd!d"Zdddd#d$Zdddd%d&Zdddd'd(Zdddd)d*Zdd+d,d-d.d/Zddgfddd0d1d2d3Zdddd4d5Zd	dd	d6d7d8Zdd9d9d:d;d<Z ddd9d=d>d?d@Z!ddAddBdCZ"dd9ddDdEdFZ#ddGddHdIZ$ddd9d9dAdJdKdLZ%ddddMdNZ&d_d+dddPdQdRZ'dSZ(dTe)dU< dVdWdXdYZ*ddd,dVd9dZdAd[d\d]Z+dS )`    )annotationsN)AnyTypeVarCallableOptional
NamedTuple)	TypeAlias   )pandasc                   @  s^   e Zd ZU ded< dZded< dZded< dZded< dZded	< dZded
< dZ	ded< dS )RemediationstrnameNzOptional[str]immediate_msgnecessary_msgzOptional[Callable[[Any], Any]]necessary_fnoptional_msgoptional_fn	error_msg)
__name__
__module____qualname____annotations__r   r   r   r   r   r    r   r   d/var/www/html/cobodadashboardai.evdpl.com/venv/lib/python3.9/site-packages/openai/lib/_validators.pyr      s   
r   OptionalDataFrameTzOptional[pd.DataFrame])boundpd.DataFramedfreturnc                 C  s8   d}t | |krdnd}dt |  d| }td|dS )z
    This validator will only print out the number of examples and recommend to the user to increase the number of examples if less than 100.
    d    z. In general, we recommend having at least a few hundred examples. We've found that performance tends to linearly increase for every doubling of the number of examplesz
- Your file contains z prompt-completion pairsnum_examplesr   r   )lenr   )r   ZMIN_EXAMPLESZoptional_suggestionr   r   r   r   num_examples_validator   s    
r%   r   )r   necessary_columnr   c                   s   dddddd d}d}d}d}| j vrdd | j D v rtddd	 fd
d}|}d d}d d}nd d}td||||dS )z[
    This validator will ensure that the necessary column is present in the dataframe.
    r   r   r   columnr   c                   s2    fdd| j D }| j|d   idd | S )Nc                   s    g | ]}t |  kr|qS r   r   lower.0cr(   r   r   
<listcomp>-       zInecessary_column_validator.<locals>.lower_case_column.<locals>.<listcomp>r   T)columnsZinplace)r1   renamer*   )r   r(   colsr   r.   r   lower_case_column,   s    z5necessary_column_validator.<locals>.lower_case_columnNc                 S  s   g | ]}t | qS r   r)   r+   r   r   r   r/   7   r0   z.necessary_column_validator.<locals>.<listcomp>r   c                   s
    | S Nr   )r   r4   r&   r   r   lower_case_column_creator9   s    z=necessary_column_validator.<locals>.lower_case_column_creatorz
- The `z ` column/key should be lowercasezLower case column name to ``z^` column/key is missing. Please make sure you name your columns/keys appropriately, then retryr&   )r   r   r   r   r   )r1   r   )r   r&   r   r   r   r   r7   r   r6   r   necessary_column_validator'   s&    
r9   prompt
completionz	list[str])r   fieldsr   c                   s   g }d}d}d}t | jdkrfdd| jD }d}|D ]8  fdd|D }t |dkr:|d  d	  d
7 }q:d| | }d| }dddfdd}td|||dS )zK
    This validator will remove additional columns from the dataframe.
    Nr	   c                   s   g | ]}| vr|qS r   r   r+   r<   r   r   r/   U   r0   z/additional_column_validator.<locals>.<listcomp>r!   c                   s   g | ]} |v r|qS r   r   r+   )acr   r   r/   X   r0   r   z9
  WARNING: Some of the additional columns/keys contain `z<` in their name. These will be ignored, and the column/key `z`` will be used instead. This could also result from a duplicate column/key in the provided file.zh
- The input file should contain exactly two columns/keys per row. Additional columns/keys present are: z Remove additional columns/keys: r   xr   c                   s   |   S r5   r   r@   r=   r   r   r   ^   s    z1additional_column_validator.<locals>.necessary_fnZadditional_columnr   r   r   r   )r$   r1   r   )r   r<   Zadditional_columnsr   r   r   warn_messageZdupsr   )r>   r<   r   additional_column_validatorK   s(    
rD   )r   fieldr   c                   s   d}d}d}|    dd  s2|     r|   dk|    B }|  j|  }d  d| }ddd fd	d
}dt| d  d}td  |||dS )zA
    This validator will ensure that no completion is empty.
    Nc                 S  s   | dkS )Nr!   r   rA   r   r   r   <lambda>q   r0   z+non_empty_field_validator.<locals>.<lambda>r!   z
- `z?` column/key should not contain empty strings. These are rows: r   r?   c                   s   | |   dk j  gdS )Nr!   Zsubset)ZdropnarA   rE   r   r   r   v   s    z/non_empty_field_validator.<locals>.necessary_fnRemove z rows with empty sZempty_rB   )applyanyZisnullreset_indexindextolistr$   r   )r   rE   r   r   r   Z
empty_rowsZempty_indexesr   rH   r   non_empty_field_validatori   s    &rP   c                   s   | j  d}|  j|  }d}d}d}t|dkrzdt| dd  d| }dt| d	}d
d
d fdd}td|||dS )zY
    This validator will suggest to the user to remove duplicate rows if they exist.
    rG   Nr   
- There are z duplicated -z sets. These are rows: rI   z duplicate rowsr   r?   c                   s   | j  dS )NrG   )Zdrop_duplicatesrA   r=   r   r   r      s    z.duplicated_rows_validator.<locals>.optional_fnduplicated_rowsr   r   r   r   )Z
duplicatedrM   rN   rO   r$   joinr   )r   r<   rS   Zduplicated_indexesr   r   r   r   r=   r   duplicated_rows_validator   s     rV   c                   s   d}d}d}t | }|dkr|ddddd  | tdkr|d	t d
 d}dt d}ddd fdd}td|||dS )zW
    This validator will suggest to the user to remove examples that are too long.
    Nopen-ended generationr   r   )dr   c                 S  s$   | j dd dd}|  j|  S )Nc                 S  s   t | jt | j dkS )Ni'  )r$   r:   r;   rA   r   r   r   rF      r0   zClong_examples_validator.<locals>.get_long_indexes.<locals>.<lambda>   )Zaxis)rK   rM   rN   rO   )rX   long_examplesr   r   r   get_long_indexes   s    z1long_examples_validator.<locals>.get_long_indexesr   rQ   z. examples that are very long. These are rows: zf
For conditional generation, and for classification the examples shouldn't be longer than 2048 tokens.rI   z long examplesr?   c                   s8    | }|kr.t jdt| d| d | |S )NzeThe indices of the long examples has changed as a result of a previously applied recommendation.
The z? long examples to be dropped are now at the following indices: 
)sysstdoutwriter$   drop)r@   Zlong_indexes_to_dropr[   Zlong_indexesr   r   r      s    z,long_examples_validator.<locals>.optional_fnrZ   rT   )infer_task_typer$   r   )r   r   r   r   ft_typer   ra   r   long_examples_validator   s"    rd   c                   s  d}d}d}d}dg d}|D ]@}|dkr@| j jd r@q | j jj|dd rXq | qbq dd}t| }|d	krtd
dS dddddd t| j dd}	| j |	k rd|	 d}td
|dS |	dkrH|	dd}
d|
 d}t	|	dkr|d| d7 }| j jdt	|	  jj|	dd rL|d|	 d7 }nd}|	dkrxd| d}ddd fd d!}td"||||d#S )$z
    This validator will suggest to add a common suffix to the prompt if one doesn't already exist in case of classification or conditional generation.
    Nz


### =>

) ->z

###

z

===

z

---

z

===>

z

--->

re   r\   Fregex\nrW   common_suffixr   r   r@   suffixr   c                 S  s   | d  |7  < | S Nr:   r   r@   rl   r   r   r   
add_suffix   s    z2common_prompt_suffix_validator.<locals>.add_suffixrl   xfixzAll prompts are identical: `zt`
Consider leaving the prompts blank if you want to do open-ended generation, otherwise ensure prompts are differentr   r   r!   z 
- All prompts end with suffix `r8   
   R. This suffix seems very long. Consider replacing with a shorter suffix, such as `z5
  WARNING: Some of your prompts contain the suffix `zZ` more than once. We strongly suggest that you review your prompts and add a unique suffixa  
- Your data does not contain a common separator at the end of your prompts. Having a separator string appended to the end of the prompt makes it clearer to the fine-tuned model where the completion should begin. See https://platform.openai.com/docs/guides/fine-tuning/preparing-your-dataset for more detail and examples. If you intend to do open-ended generation, then you should leave the prompts emptyzAdd a suffix separator `z` to all promptsr?   c                   s
    | S r5   r   rA   ro   Zsuggested_suffixr   r   r      s    z3common_prompt_suffix_validator.<locals>.optional_fncommon_completion_suffixr   r   r   r   r   )
r:   r   containsrL   replacerb   r   get_common_xfixallr$   )r   r   r   r   r   suffix_optionssuffix_optiondisplay_suggested_suffixrc   ri   common_suffix_new_line_handledr   ru   r   common_prompt_suffix_validator   sR    

(
r   c                   s   d}d}d}d}t | jdd  dkr0tddS dddd	d
d| j k rZtddS  dkrd  d}|t k r|d7 }d  d}ddd fdd}td|||dS )zd
    This validator will suggest to remove a common prefix from the prompt if a long one exist.
       Nprefixrp   r!   common_prefixrj   r   )r@   r   r   c                 S  s   | d j t|d  | d< | S rm   r   r$   )r@   r   r   r   r   remove_common_prefix  s    z<common_prompt_prefix_validator.<locals>.remove_common_prefixz"
- All prompts start with prefix `r8   z. Fine-tuning doesn't require the instruction specifying the task, or a few-shot example scenario. Most of the time you should only add the input data into the prompt, and the desired output into the completionRemove prefix `z` from all promptsr?   c                   s
   |  S r5   r   rA   r   r   r   r   r   !  s    z3common_prompt_prefix_validator.<locals>.optional_fnZcommon_prompt_prefixrT   )rz   r:   r   r{   r$   r   ZMAX_PREFIX_LENr   r   r   r   r   r   common_prompt_prefix_validator  s,    

r   c                   s   d}t | jdd t dko( d dkt |k r@tddS ddddd	d
d| j k rltddS d  d}d  d}ddd fdd}td|||dS )zh
    This validator will suggest to remove a common prefix from the completion if a long one exist.
       r   rp   r    r   rj   r   )r@   r   	ws_prefixr   c                 S  s4   | d j t|d  | d< |r0d| d  | d< | S )Nr;   r   r   )r@   r   r   r   r   r   r   7  s    z@common_completion_prefix_validator.<locals>.remove_common_prefixz&
- All completions start with prefix `z_`. Most of the time you should only add the output data into the completion, without any prefixr   z` from all completionsr?   c                   s   |  S r5   r   rA   r   r   r   r   r   r   E  s    z7common_completion_prefix_validator.<locals>.optional_fnZcommon_completion_prefixrT   )rz   r;   r$   r   r{   r   r   r   r   "common_completion_prefix_validator,  s"    

r   c                   sz  d}d}d}d}t | }|dks(|dkr2tddS t| jdd}| j|k rld| d	| d
}td|dS dg d}|D ]$}| jjj|dd rq|| qq|dd}	dddddd |dkr8|dd}
d|
 d
}t	|dkr|d|	 d
7 }| jjdt	|  jj|dd r<|d| d7 }nd}|dkrhd|	 d}ddd fd d!}td"||||d#S )$z
    This validator will suggest to add a common suffix to the completion if one doesn't already exist in case of classification or conditional generation.
    NrW   classificationri   rj   rl   rp   z All completions are identical: `zJ`
Ensure completions are different, otherwise the model will just repeat `r8   rr   z [END])	r\   .z ENDz***z+++z&&&z$$$z@@@z%%%Frf   r\   rh   r   rk   c                 S  s   | d  |7  < | S Nr;   r   rn   r   r   r   ro   v  s    z6common_completion_suffix_validator.<locals>.add_suffixr!   z$
- All completions end with suffix `rs   rt   z9
  WARNING: Some of your completions contain the suffix `zU` more than once. We suggest that you review your completions and add a unique endingaH  
- Your data does not contain a common ending at the end of your completions. Having a common ending string appended to the end of the completion makes it clearer to the fine-tuned model where the completion should end. See https://platform.openai.com/docs/guides/fine-tuning/preparing-your-dataset for more detail and examples.zAdd a suffix ending `z` to all completionsr?   c                   s
    | S r5   r   rA   ru   r   r   r     s    z7common_completion_suffix_validator.<locals>.optional_fnrv   rw   )
rb   r   rz   r;   r{   r   rx   rL   ry   r$   )r   r   r   r   r   rc   ri   r|   r}   r~   r   r   ru   r   "common_completion_suffix_validatorP  sL    

(
r   c                 C  sd   ddddd}d}d}d}| j jdd  dksH| j jd d dkrTd	}d
}|}td|||dS )z
    This validator will suggest to add a space at the start of the completion if it doesn't already exist. This helps with tokenization.
    r   r?   c                 S  s   | d  dd | d< | S )Nr;   c                 S  s   |  drdnd|  S )Nr   r!   )
startswith)rJ   r   r   r   rF     r0   zLcompletions_space_start_validator.<locals>.add_space_start.<locals>.<lambda>)rK   rA   r   r   r   add_space_start  s    z:completions_space_start_validator.<locals>.add_space_startNrY   r   r   z
- The completion should start with a whitespace character (` `). This tends to produce better results due to the tokenization we use. See https://platform.openai.com/docs/guides/fine-tuning/preparing-your-dataset for more detailsz=Add a whitespace character to the beginning of the completionZcompletion_space_startrT   )r;   r   nuniquevaluesr   )r   r   r   r   r   r   r   r   !completions_space_start_validator  s    ,r   r   zRemediation | Noner'   c                   sv   ddd fdd}|    dd  }|    dd  }|d |krrtd	d
  d  dd  d|dS dS )zt
    This validator will suggest to lowercase the column values, if more than a third of letters are uppercase.
    r   r?   c                   s   |   j  |  < | S r5   r)   rA   r.   r   r   
lower_case  s    z(lower_case_validator.<locals>.lower_casec                 S  s   t dd | D S )Nc                 s  s"   | ]}|  r| rd V  qdS rY   N)isalphaisupperr+   r   r   r   	<genexpr>  r0   9lower_case_validator.<locals>.<lambda>.<locals>.<genexpr>sumrA   r   r   r   rF     r0   z&lower_case_validator.<locals>.<lambda>c                 S  s   t dd | D S )Nc                 s  s"   | ]}|  r| rd V  qdS r   )r   islowerr+   r   r   r   r     r0   r   r   rA   r   r   r   rF     r0   r	   r   z
- More than a third of your `z%` column/key is uppercase. Uppercase zs tends to perform worse than a mixture of case encountered in normal language. We recommend to lower case the data if that makes sense in your domain. See https://platform.openai.com/docs/guides/fine-tuning/preparing-your-dataset for more detailsz'Lowercase all your data in column/key `r8   rT   N)rK   r   r   )r   r(   r   Zcount_upperZcount_lowerr   r.   r   lower_case_validator  s    
r   z'tuple[pd.DataFrame | None, Remediation])fnamer<   r   c              
   C  s  d}d}d}d}d}t j| rzJ|  dsB|  dr|  drTdnd\}}d| d}d| d	}tj| |td
d}n|  drd}d}t	| }	|	j
}
t|
dkr|d7 }tj| tdd}n|  drVd}d}t| d>}| }tjdd |dD |tdd}W d   n1 sH0    Y  n|  drtj| dtdd}t|dkrld}d}tj| tdd}n n|  dr,zFtj| dtdd}t|dkrtj| tdd}nd }d}W n( ty(   tj| tdd}Y n0 n@d!}d"| v r\|d#|  d$| d"d%  d&7 }n|d#|  d'7 }W nB ttfy   | d"d%  }d(|  d)| d*| d+}Y n0 nd,|  d-}td.|||d/}||fS )0z
    This function will read a file saved in .csv, .json, .txt, .xlsx or .tsv format using pandas.
     - for .xlsx it will read the first sheet
     - for .txt it will assume completions and split on newline
    Nz.csvz.tsv)ZCSV,)ZTSV	z=
- Based on your file extension, your file is formatted as a z filezYour format `z` will be converted to `JSONL`)sepdtyper!   z.xlsxzH
- Based on your file extension, your file is formatted as an Excel filez/Your format `XLSX` will be converted to `JSONL`rY   z
- Your Excel file contains more than one sheet. Please either save as csv or ensure all data is present in the first sheet. WARNING: Reading only the first sheet...)r   z.txtz9
- Based on your file extension, you provided a text filez.Your format `TXT` will be converted to `JSONL`rc                 S  s   g | ]}d |gqS )r!   r   )r,   liner   r   r   r/     r0   z#read_any_format.<locals>.<listcomp>r\   )r1   r   .jsonlT)linesr   z^
- Your JSONL file appears to be in a JSON format. Your file will be converted to JSONL formatz/Your format `JSON` will be converted to `JSONL`z.jsonz^
- Your JSON file appears to be in a JSONL format. Your file will be converted to JSONL formatz]Your file must have one of the following extensions: .CSV, .TSV, .XLSX, .TXT, .JSON or .JSONLr   z Your file `z` ends with the extension `.z` which is not supported.z` is missing a file extension.zYour file `z!` does not appear to be in valid z9 format. Please ensure your file is formatted as a valid z file.zFile z does not exist.read_any_format)r   r   r   r   )ospathisfiler*   endswithpdZread_csvr   ZfillnaZ	ExcelFileZsheet_namesr$   Z
read_excelopenreadZ	DataFramesplit	read_json
ValueError	TypeErrorupperr   )r   r<   remediationr   r   r   r   Zfile_extension_str	separatorZxlsZsheetsfcontentr   r   r   r     s    

(
" r   c                 C  s,   t | }d}|dkr d| d}td|dS )z
    This validator will infer the likely fine-tuning format of the data, and display it to the user if it is classification.
    It will also suggest to use ada and explain train/validation split benefits.
    Nr   zK
- Based on your data it seems like you're trying to fine-tune a model for z
- For classification, we recommend you try one of the faster and cheaper models, such as `ada`
- For classification, you can estimate the expected model performance by keeping a held out dataset, which is not used for trainingr"   r#   )rb   r   )r   rc   r   r   r   r   format_inferrer_validator  s
    r   )r   r   r   c                 C  sb   |j dur2tjd|j d|j  d td |jdurJtj|j |jdur^|| } | S )zs
    This function will apply a necessary remediation to a dataframe, or print an error message if one exists.
    Nz

ERROR in z validator: z

Aborting...rY   )	r   r]   stderrr_   r   exitr   r^   r   )r   r   r   r   r   apply_necessary_remediation(  s    




r   bool)
input_textauto_acceptr   c                 C  s.   t j|  |r t jd dS t  dkS )NzY
Tn)r]   r^   r_   inputr*   )r   r   r   r   r   accept_suggestion6  s
    r   ztuple[pd.DataFrame, bool])r   r   r   r   c                 C  sj   d}d|j  d}|j durBt||rB|jdus4J || } d}|jdurbtjd|j d | |fS )zc
    This function will apply an optional remediation to a dataframe, based on the user input.
    Fz- [Recommended] z [Y/n]: NTz- [Necessary] r\   )r   r   r   r   r]   r^   r_   )r   r   r   optional_appliedr   r   r   r   apply_optional_remediation>  s    



r   Nonec                 C  sr   t | }d}|dkr&t| }|d }n| jdd }|d }ddd	d
d}||d }tjd| d dS )z?
    Estimate the time it'll take to fine-tune the dataset
    g      ?r   g
ףp=
?T)rN   g|?5^?floatr   )timer   c                 S  sh   | dk rt | d dS | dk r4t | d d dS | dk rPt | d d dS t | d d dS d S )	N<   r	   z secondsi  z minutesiQ z hoursz days)round)r   r   r   r   format_time]  s    z.estimate_fine_tuning_time.<locals>.format_time   z:Once your model starts training, it'll approximately take z~ to train a `curie` model, and less for `ada` and `babbage`. Queue will approximately take half an hour per job ahead of you.
N)rb   r$   Zmemory_usager   r]   r^   r_   )r   	ft_formatZexpected_timer"   sizer   Ztime_stringr   r   r   estimate_fine_tuning_timeP  s    


r   )r   r   r   c                   sf   |rddgndg}d}|dkr*d| dnd fdd|D }t d	d
 |D sX|S |d7 }qd S )NZ_train_validr!   r   z ()c                   s,   g | ]$}t j d   d|  dqS )r   Z	_preparedr   )r   r   splitext)r,   rl   r   Zindex_suffixr   r   r/   r  r0   z!get_outfnames.<locals>.<listcomp>c                 s  s   | ]}t j|V  qd S r5   )r   r   r   )r,   r   r   r   r   r   s  r0   z get_outfnames.<locals>.<genexpr>rY   )rL   )r   r   suffixesiZcandidate_fnamesr   r   r   get_outfnamesm  s    r   ztuple[int, object]c                 C  s.   | j  }d }|dkr&| j  jd }||fS )Nr	   r   )r;   r   Zvalue_countsrN   )r   	n_classes	pos_classr   r   r   get_classification_hyperparamsx  s
    
r   )r   r   any_remediationsr   r   c                 C  s  t | }t| jdd}t| jdd}d}d}|dkrBt||rBd}d}	|dd	}
|dd	}t|d
krvd| dnd}d}|s|stj	d| d|	 d|
 d| d	 t
|  nt||rzt||}|rt|dkrd|d
 v rd|d v sJ d}tt| | tt| d }| j|dd}| |j}|ddg j|d
 ddddd |ddg j|d ddddd t| \}}|	d7 }	|dkr|	d | d7 }	n|	d!| 7 }	n2t|dksJ | ddg j|d
 ddddd |rd"ndd# d$| }|rd%|d  dnd}t|
d
kr2dn
d&|
 d}tj	d'| d(|d
  d| |	 d)| | d t
|  ntj	d* dS )+aQ  
    This function will write out a dataframe to a file, if the user would like to proceed, and also offer a fine-tuning command with the newly created file.
    For classification it will optionally ask the user if they would like to split the data into train/valid files, and modify the suggested command to include the valid set.
    rl   rp   FzQ- [Recommended] Would you like to split into training and validation set? [Y/n]: r   Tr!   r\   rh   r   z Make sure to include `stop=["z;"]` so that the generated texts ends at the expected place.z@

Your data will be written to a new JSONL file. Proceed [Y/n]: zK
You can use your file for fine-tuning:
> openai api fine_tunes.create -t ""ue   

After you’ve fine-tuned a model, remember that your prompt has to end with the indicator string `zX` for the model to start generating completions, rather than continuing with the prompt.r	   trainZvalidrY   i  g?*   )r   Zrandom_stater:   r;   recordsN)r   ZorientZforce_asciiindentz! --compute_classification_metricsz" --classification_positive_class "z --classification_n_classes rJ   z to `z` and `z -v "uc   After you’ve fine-tuned a model, remember that your prompt has to end with the indicator string `z
Wrote modified filezd`
Feel free to take a look!

Now use that file when fine-tuning:
> openai api fine_tunes.create -t "z

z#Aborting... did not write the file
)rb   rz   r:   r;   r   ry   r$   r]   r^   r_   r   r   maxintsampler`   rN   to_jsonr   rU   )r   r   r   r   r   Zcommon_prompt_suffixrv   r   r   Zadditional_paramsZ%common_prompt_suffix_new_line_handledZ)common_completion_suffix_new_line_handledZoptional_ending_stringfnamesZMAX_VALID_EXAMPLESZn_trainZdf_trainZdf_validr   r   Zfiles_stringZvalid_stringZseparator_reminderr   r   r   write_out_file  sn    


(


(
r   c                 C  s>   d}t | jj dkrdS t| j t| | k r:dS dS )z>
    Infer the likely fine-tuning task type from the data
       r   rW   r   zconditional generation)r   r:   r   r$   r;   unique)r   ZCLASSIFICATION_THRESHOLDr   r   r   rb     s    rb   rl   )seriesrq   r   c                 C  sl   d}|dkr$| j t|d  d n| j dt|d  }| dkrJqhq||jd kr\qhq|jd }q|S )zQ
    Finds the longest common suffix or prefix of all the values in a series
    r!   rl   rY   Nr   )r   r$   r   r   )r   rq   Zcommon_xfixZcommon_xfixesr   r   r   rz     s    4rz   z,Callable[[pd.DataFrame], Remediation | None]r   	Validatorzlist[Validator])r   c                   C  s2   t dd dd tttttdd dd tttt	t
gS )Nc                 S  s
   t | dS rm   r9   rA   r   r   r   rF     r0   z get_validators.<locals>.<lambda>c                 S  s
   t | dS r   r   rA   r   r   r   rF     r0   c                 S  s
   t | dS rm   r   rA   r   r   r   rF     r0   c                 S  s
   t | dS r   r   rA   r   r   r   rF     r0   )r%   rD   rP   r   rV   rd   r   r   r   r   r   r   r   r   r   get_validators  s     r   zCallable[..., Any])r   r   r   
validatorsr   write_out_file_funcr   c                 C  s   g }|d ur| | |D ](}|| }|d ur| | t| |} qtdd |D }tdd |D }	d}
|rtjd |D ]}t| ||\} }|
p|}
qntjd |
p|	}|| ||| d S )Nc                 S  s$   g | ]}|j d us|jd ur|qS r5   )r   r   r,   r   r   r   r   r/     s   z$apply_validators.<locals>.<listcomp>c                 S  s   g | ]}|j d ur|qS r5   )r   r   r   r   r   r/     r0   Fz?

Based on the analysis we will perform the following actions:
z

No remediations found.
)appendr   rL   r]   r^   r_   r   )r   r   r   r   r   r   Zoptional_remediations	validatorZ&any_optional_or_necessary_remediationsZany_necessary_appliedZany_optional_appliedr   Z!any_optional_or_necessary_appliedr   r   r   apply_validators  s2    

r   )r;   )rl   ),
__future__r   r   r]   typingr   r   r   r   r   Ztyping_extensionsr   _extrasr
   r   r   r   r%   r9   rD   rP   rV   rd   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rb   rz   r   r   r   r   r   r   r   r   <module>   sD   
$%D'$DYK