U
    h+                     @  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rdd
lmZ G dd deZ dddddddZ!dd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Fieldroot_validator	validator)TimeoutZPOWERBI_BASE_URLz"https://api.powerbi.com/v1.0/myorg)TokenCredentialc                   @  s  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< G dd dZeddddddddZeddd d d!d"d#Zedd$d%d&Zedd$d'd(Zd)d$d*d+Zdd$d,d-Zedd$d.d/ZdLd0d1dd2d3Zddd4d5d6Zdddd7d8ZdMd0ddd9d:ZdNd0ddd;d<Zdd=d>d?d@Zdd=d>dAdBZddCdDdEdFZ ddGdDdHdIZ!ddGdDdJdKZ"dS )O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_idz	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_factoryzDict[str, str]schemaszOptional[aiohttp.ClientSession]
aiosessionc                   @  s   e Zd ZdZdS )zPowerBIDataset.ConfigTN)__name__
__module____qualname__Zarbitrary_types_allowed r(   r(   I/tmp/pip-unpacked-wheel-9gdii04g/langchain_community/utilities/powerbi.pyConfig+   s   r*   T)Zallow_reuse)r   returnc                 C  s   dd |D S )zFix the table names.c                 S  s   g | ]}t |qS r(   fix_table_name.0tabler(   r(   r)   
<listcomp>1   s     z2PowerBIDataset.fix_table_names.<locals>.<listcomp>r(   )clsr   r(   r(   r)   fix_table_names.   s    zPowerBIDataset.fix_table_names)prezDict[str, Any])valuesr+   c                 C  s    d|ksd|kr|S t ddS )z?Validate that at least one of token and credentials is present.r   r   z.Please provide either a credential or a token.N)
ValueError)r2   r5   r(   r(   r)   token_or_credential_present3   s    z*PowerBIDataset.token_or_credential_present)r+   c                 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(   r)   request_url:   s    zPowerBIDataset.request_urlc              
   C  s   | j rdd| j  dS ddlm} | jrtz| jdj }dd| dW S  tk
rr } z|d|W 5 d}~X Y nX |d	dS )
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(   r)   headersA   s(    zPowerBIDataset.headerszIterable[str]c                 C  s   | j S )zGet names of tables available.r   r9   r(   r(   r)   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(   )r/   keyvaluer(   r(   r)   r1   c   s     z.PowerBIDataset.get_schemas.<locals>.<listcomp>z9No known schema's yet. Use the schema_powerbi tool first.)r#   joinitemsr9   r(   r(   r)   get_schemas`   s    zPowerBIDataset.get_schemasc                 C  s   |   S )z-Information about all tables in the database.)get_table_infor9   r(   r(   r)   
table_infof   s    zPowerBIDataset.table_infozOptional[Union[List[str], str]]zOptional[List[str]]c                   s   |dk	rt |tr~t|dkr~|d dkr~dd |D }fdd|D   r`tdd   fd	d|D }|rz|S dS t |tr|dkr|jkrtd
| dS t|gS jS )zHGet the tables names that need to be queried, after checking they exist.Nr    c                 S  s   g | ]}t |qS r(   r,   r.   r(   r(   r)   r1   u   s     z7PowerBIDataset._get_tables_to_query.<locals>.<listcomp>c                   s   g | ]}| j kr|qS r(   rB   r.   r9   r(   r)   r1   v   s    
 z!Table(s) %s not found in dataset.rD   c                   s   g | ]}| kr|qS r(   r(   r.   )non_existing_tablesr(   r)   r1   ~   s     zTable %s not found in dataset.)	
isinstancelistlenloggerwarningrG   r   r   r-   )r:   r   Zfixed_tablestablesr(   )rM   r:   r)   _get_tables_to_queryk   s4    





z#PowerBIDataset._get_tables_to_query)tables_todor+   c                   s    fdd|D S )z-Get the tables that still need to be queried.c                   s   g | ]}| j kr|qS r(   )r#   r.   r9   r(   r)   r1      s     
 z3PowerBIDataset._get_tables_todo.<locals>.<listcomp>r(   )r:   rU   r(   r9   r)   _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 | ]\}}| kr|qS r(   r(   )r/   r0   ZschemarB   r(   r)   r1      s     z9PowerBIDataset._get_schema_for_tables.<locals>.<listcomp>rD   )r#   rH   rG   )r:   r   r#   r(   rB   r)   _get_schema_for_tables   s    
z%PowerBIDataset._get_schema_for_tablesc                 C  s>   |  |}|dkrdS | |}|D ]}| | q$| |S )'Get information about specified tables.NNo (valid) tables requested.)rT   rV   _get_schemarW   )r:   r   tables_requestedrU   r0   r(   r(   r)   rJ      s    

zPowerBIDataset.get_table_infoc                   sH     |}|dkrdS  |}tj fdd|D  I dH   |S )rX   NrY   c                   s   g | ]}  |qS r(   )_aget_schemar.   r9   r(   r)   r1      s     z2PowerBIDataset.aget_table_info.<locals>.<listcomp>)rT   rV   asyncioZgatherrW   )r:   r   r[   rU   r(   r9   r)   aget_table_info   s    

zPowerBIDataset.aget_table_infoNoner0   r+   c              
   C  s   z@|  d| j d| d}t|d d d d d | j|< W nb tk
rj   td| d	| j|< Y n: tk
r } ztd
|| d	| j|< W 5 d}~X Y nX dS )Get the schema for a table.EVALUATE TOPN(rD   )resultsr   rS   rows'Timeout while getting table info for %sunknown)Error while getting table info for %s: %sN)runr!   
json_to_mdr#   r   rQ   rR   r?   r:   r0   resultr@   r(   r(   r)   rZ      s    &zPowerBIDataset._get_schemac              
     s   zF|  d| j d| dI dH }t|d d d d d | j|< W nb tk
rp   td	| d
| j|< Y n: tk
r } ztd|| d
| j|< W 5 d}~X Y nX dS )ra   rb   rD   rc   Nrd   r   rS   re   rf   rg   rh   )arunr!   rj   r#   r   rQ   rR   r?   rk   r(   r(   r)   r\      s    
&zPowerBIDataset._aget_schemazdict[str, Any])commandr+   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:   rn   r(   r(   r)   _create_json_content   s    
z#PowerBIDataset._create_json_contentr   c                 C  s>   t d| tj| j| || jdd}|jdkr6dS | S )zAExecute a DAX command and return a json representing the results.Running command: %sr   )jsonrA   timeout  FTokenError: Could not login to PowerBI, please check your credentials.)	rQ   debugrequestspostr;   rp   rA   status_coderr   )r:   rn   responser(   r(   r)   ri      s    
zPowerBIDataset.runc                   s^  t d| | jr| jj| j| j| |tddd4 I dH J}|jdkr^W 5 Q I dH R  dS |j	|j
dI dH }|W  5 Q I dH R  S Q I dH R X t 4 I dH }|j| j| j| |tddd4 I dH n}|jdkrW 5 Q I dH R  W 5 Q I dH R  dS |j	|j
dI dH }|W  5 Q I dH R  W  5 Q I dH R  S Q I dH R X W 5 Q I dH R X dS )	z;Execute a DAX command and return the result asynchronously.rq   r   )total)rA   rr   rs   Nrt   ru   )content_type)rQ   rv   r$   rx   r;   rA   rp   r
   statusrr   r|   aiohttpZClientSession)r:   rn   rz   Zresponse_jsonsessionr(   r(   r)   rm      s2    
"$zPowerBIDataset.arun)N)N)N)#r%   r&   r'   __doc____annotations__r   r   r   r   r   r!   dictr#   r$   r*   r   r3   r   r7   propertyr;   rA   rC   rI   rK   rT   rV   rW   rJ   r^   rZ   r\   rp   ri   rm   r(   r(   r(   r)   r      sH   

   r   z'List[Dict[str, Union[str, int, float]]]r   r   )json_contents
table_namer+   c                 C  s   t | dkrdS d}| d  }|D ]>}|dddd |rR|| dd |d| d7 }q$|d7 }| D ]*}| D ]}|d| d7 }q||d7 }qp|S )	z*Convert a JSON object to a markdown table.r   rL   [.]z|  z|
)rP   keysreplacer5   )r   r   Z	output_mdrA   headerrowrF   r(   r(   r)   rj      s    
rj   r`   c                 C  s,   d| kr(|  ds(| ds(d|  dS | S )z9Add single quotes around table names that contain spaces.r   ')
startswithendswith)r0   r(   r(   r)   r-     s    r-   )N)#r   
__future__r   r]   loggingostypingr   r   r   r   r   r   r	   r~   rw   r
   r   Zlangchain_core.pydantic_v1r   r   r   r   Zrequests.exceptionsr   	getLoggerr%   rQ   getenvr8   Zazure.core.credentialsr   r   rj   r-   r(   r(   r(   r)   <module>   s&   $
 d 