o
    Zh+                     @  s   d Z ddlmZ ddlZddlZddlZddlmZmZm	Z	m
Z
mZmZmZ ddlZddlZddlmZmZ ddlmZmZmZmZ ddlmZ eeZedd	Zer[dd
lmZ G dd deZ 	ddddZ!dddZ"dS )z#Wrapper around a Power BI endpoint.    )annotationsN)TYPE_CHECKINGAnyDictIterableListOptionalUnion)ClientTimeoutServerTimeoutError)	BaseModel
ConfigDictFieldmodel_validator)TimeoutZPOWERBI_BASE_URLz"https://api.powerbi.com/v1.0/myorg)TokenCredentialc                   @  sV  e Zd ZU dZded< ded< dZded< dZd	ed
< dZded< dZded< e	ddddZ
ded< e	edZded< dZded< eddZeddedHd d!ZedId"d#ZedJd$d%ZdKd'd(ZdId)d*ZedId+d,Z	dLdMd/d0ZdNd2d3ZdOd4d5Z	dLdPd6d7Z	dLdPd8d9ZdQd<d=ZdQd>d?ZdRdBdCZ dSdDdEZ!dSdFdGZ"dS )TPowerBIDatasetaO  Create PowerBI engine from dataset ID and credential or token.

    Use either the credential or a supplied token to authenticate.
    If both are supplied the credential is used to generate a token.
    The impersonated_user_name is the UPN of a user to be impersonated.
    If the model is not RLS enabled, this will be ignored.
    str
dataset_id	List[str]table_namesNOptional[str]group_idzOptional[TokenCredential]
credentialtokenimpersonated_user_name   r   
   )defaultgtleintsample_rows_in_table_info)default_factoryDict[str, str]schemaszOptional[aiohttp.ClientSession]
aiosessionT)Zarbitrary_types_allowedbefore)modevaluesDict[str, Any]returnr   c                 C  s:   | dg }dd |D |d< d|v sd|v r|S td)z?Validate that at least one of token and credentials is present.r   c                 S     g | ]}t |qS  fix_table_name.0tabler-   r-   \/var/www/html/lang_env/lib/python3.10/site-packages/langchain_community/utilities/powerbi.py
<listcomp>9       z2PowerBIDataset.validate_params.<locals>.<listcomp>r   r   z.Please provide either a credential or a token.)get
ValueError)clsr)   r   r-   r-   r3   validate_params4   s
   zPowerBIDataset.validate_paramsc                 C  s2   | j rt d| j  d| j dS t d| j dS )zGet the request url.z/groups/z
/datasets/z/executeQueries)r   BASE_URLr   selfr-   r-   r3   request_url>   s   zPowerBIDataset.request_urlc              
   C  sr   | j rdd| j  dS ddlm} | jr5z| jdj }dd| dW S  ty4 } z|d|d}~ww |d	)
zGet the token.zapplication/jsonzBearer )zContent-TypeAuthorizationr   )ClientAuthenticationErrorz1https://analysis.windows.net/powerbi/api/.defaultz4Could not get a token from the supplied credentials.Nz No credential or token supplied.)r   Zazure.core.exceptionsr?   r   	get_token	Exception)r<   r?   r   excr-   r-   r3   headersE   s0   zPowerBIDataset.headersIterable[str]c                 C  s   | j S )zGet names of tables available.r   r;   r-   r-   r3   get_table_names`   s   zPowerBIDataset.get_table_namesc                 C  s$   | j rddd | j  D S dS )zGet the available schema's., c                 S  s   g | ]\}}| d | qS )z: r-   )r1   keyvaluer-   r-   r3   r4   g   s    z.PowerBIDataset.get_schemas.<locals>.<listcomp>z9No known schema's yet. Use the schema_powerbi tool first.)r%   joinitemsr;   r-   r-   r3   get_schemasd   s   zPowerBIDataset.get_schemasc                 C  s   |   S )z-Information about all tables in the database.)get_table_infor;   r-   r-   r3   
table_infoj   s   zPowerBIDataset.table_infoOptional[Union[List[str], str]]Optional[List[str]]c                   s   |durZt |tr?t|dkr?|d dkr?dd |D }fdd|D   r0tdd   fd	d|D }|r=|S dS t |trZ|dkrZ|jvrUtd
| dS t|gS jS )zHGet the tables names that need to be queried, after checking they exist.Nr    c                 S  r,   r-   r.   r0   r-   r-   r3   r4   y   r5   z7PowerBIDataset._get_tables_to_query.<locals>.<listcomp>c                      g | ]	}| j vr|qS r-   rE   r0   r;   r-   r3   r4   z   s    z!Table(s) %s not found in dataset.rG   c                   s   g | ]}| vr|qS r-   r-   r0   )non_existing_tablesr-   r3   r4      s    zTable %s not found in dataset.)	
isinstancelistlenloggerwarningrJ   r   r   r/   )r<   r   Zfixed_tablestablesr-   )rS   r<   r3   _get_tables_to_queryo   s0   



z#PowerBIDataset._get_tables_to_querytables_todoc                   s    fdd|D S )z-Get the tables that still need to be queried.c                   rR   r-   )r%   r0   r;   r-   r3   r4      s    z3PowerBIDataset._get_tables_todo.<locals>.<listcomp>r-   )r<   r[   r-   r;   r3   _get_tables_todo   s   zPowerBIDataset._get_tables_todoc                   s"    fdd| j  D }d|S )z=Create a string of the table schemas for the supplied tables.c                   s   g | ]
\}}| v r|qS r-   r-   )r1   r2   ZschemarE   r-   r3   r4      s    z9PowerBIDataset._get_schema_for_tables.<locals>.<listcomp>rG   )r%   rK   rJ   )r<   r   r%   r-   rE   r3   _get_schema_for_tables   s   

z%PowerBIDataset._get_schema_for_tablesc                 C  s>   |  |}|du rdS | |}|D ]}| | q| |S )'Get information about specified tables.NNo (valid) tables requested.)rZ   r\   _get_schemar]   )r<   r   tables_requestedr[   r2   r-   r-   r3   rM      s   


zPowerBIDataset.get_table_infoc                   sJ     |}|du rdS  |}tj fdd|D  I dH   |S )r^   Nr_   c                   s   g | ]}  |qS r-   )_aget_schemar0   r;   r-   r3   r4      s    z2PowerBIDataset.aget_table_info.<locals>.<listcomp>)rZ   r\   asynciogatherr]   )r<   r   ra   r[   r-   r;   r3   aget_table_info   s   


zPowerBIDataset.aget_table_infor2   Nonec              
   C  s   z!|  d| j d| d}t|d d d d d | j|< W dS  ty6   td| d	| j|< Y dS  tyT } ztd
|| d	| j|< W Y d}~dS d}~ww )Get the schema for a table.EVALUATE TOPN(rG   )resultsr   rY   rows'Timeout while getting table info for %sunknown)Error while getting table info for %s: %sN)runr"   
json_to_mdr%   r   rW   rX   rA   r<   r2   resultrB   r-   r-   r3   r`      s   (zPowerBIDataset._get_schemac              
     s   z$|  d| j d| dI dH }t|d d d d d | j|< W dS  ty:   td	| d
| j|< Y dS  tyX } ztd|| d
| j|< W Y d}~dS d}~ww )rg   rh   rG   ri   Nrj   r   rY   rk   rl   rm   rn   )arunr"   rp   r%   r   rW   rX   rA   rq   r-   r-   r3   rb      s   
(zPowerBIDataset._aget_schemacommanddict[str, Any]c                 C  s   d| ig| j ddidS )z(Create the json content for the request.queryZincludeNullsT)ZqueriesZimpersonatedUserNameZserializerSettings)r   )r<   rt   r-   r-   r3   _create_json_content   s   
z#PowerBIDataset._create_json_contentc                 C  s@   t d| tj| j| || jdd}|jdkr	 dS | S )zAExecute a DAX command and return a json representing the results.Running command: %sr   )jsonrC   timeout  FTokenError: Could not login to PowerBI, please check your credentials.)	rW   debugrequestspostr=   rw   rC   status_codery   )r<   rt   responser-   r-   r3   ro      s   
zPowerBIDataset.runc              
     s  t d| | jrS| jj| j| j| |tddd4 I dH (}|jdkr2	 W d  I dH  dS |j	|j
dI dH }|W  d  I dH  S 1 I dH sNw   Y  t 4 I dH g}|j| j| j| |tddd4 I dH ;}|jdkr	 W d  I dH  W d  I dH  dS |j	|j
dI dH }|W  d  I dH  W  d  I dH  S 1 I dH sw   Y  W d  I dH  dS 1 I dH sw   Y  dS )	z;Execute a DAX command and return the result asynchronously.rx   r   )total)rC   ry   rz   Nr{   r|   )content_type)rW   r}   r&   r   r=   rC   rw   r
   statusry   r   aiohttpZClientSession)r<   rt   r   Zresponse_jsonsessionr-   r-   r3   rs      sD   
,

	.zPowerBIDataset.arun)r)   r*   r+   r   )r+   r   )r+   r$   )r+   rD   N)r   rO   r+   rP   )r[   r   r+   r   )r   r   r+   r   )r   rO   r+   r   )r2   r   r+   rf   )rt   r   r+   ru   )rt   r   r+   r   )#__name__
__module____qualname____doc____annotations__r   r   r   r   r   r"   dictr%   r&   r   Zmodel_configr   classmethodr9   propertyr=   rC   rF   rL   rN   rZ   r\   r]   rM   re   r`   rb   rw   ro   rs   r-   r-   r-   r3   r      sL   
 







r   json_contents'List[Dict[str, Union[str, int, float]]]
table_namer   r+   r   c                 C  s   t | dkrdS d}| d  }|D ]}|dddd |r)|| dd |d| d7 }q|d7 }| D ]}| D ]
}|d| d7 }q>|d7 }q8|S )	z*Convert a JSON object to a markdown table.r   rQ   [.]z|  z|
)rV   keysreplacer)   )r   r   Z	output_mdrC   headerrowrI   r-   r-   r3   rp      s   
rp   r2   c                 C  s,   d| v r|  ds| dsd|  dS | S )z9Add single quotes around table names that contain spaces.r   ')
startswithendswith)r2   r-   r-   r3   r/     s   r/   r   )r   r   r   r   r+   r   )r2   r   r+   r   )#r   
__future__r   rc   loggingostypingr   r   r   r   r   r   r	   r   r~   r
   r   Zpydanticr   r   r   r   Zrequests.exceptionsr   	getLoggerr   rW   getenvr:   Zazure.core.credentialsr   r   rp   r/   r-   r-   r-   r3   <module>   s(    $
 c