o
    ȳg+                     @  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)Timeout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)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/   a/var/www/html/chatdoc2/venv/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/   r5   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/   r5   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   azure.core.exceptionsrA   r   	get_token	Exception)r>   rA   r   excr/   r/   r5   headersE   s0   zPowerBIDataset.headersIterable[str]c                 C  s   | j S )zGet names of tables available.r   r=   r/   r/   r5   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/   )r3   keyvaluer/   r/   r5   r6   g   s    z.PowerBIDataset.get_schemas.<locals>.<listcomp>z9No known schema's yet. Use the schema_powerbi tool first.)r&   joinitemsr=   r/   r/   r5   get_schemasd   s   zPowerBIDataset.get_schemasc                 C  s   |   S )z-Information about all tables in the database.)get_table_infor=   r/   r/   r5   
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/   r0   r2   r/   r/   r5   r6   y   r7   z7PowerBIDataset._get_tables_to_query.<locals>.<listcomp>c                      g | ]	}| j vr|qS r/   rH   r2   r=   r/   r5   r6   z   s    z!Table(s) %s not found in dataset.rJ   c                   s   g | ]}| vr|qS r/   r/   r2   )non_existing_tablesr/   r5   r6      s    zTable %s not found in dataset.)	
isinstancelistlenloggerwarningrM   r   r   r1   )r>   r   fixed_tablestablesr/   )rV   r>   r5   _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                   rU   r/   )r&   r2   r=   r/   r5   r6      s    z3PowerBIDataset._get_tables_todo.<locals>.<listcomp>r/   )r>   r_   r/   r=   r5   _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/   )r3   r4   schemarH   r/   r5   r6      s    z9PowerBIDataset._get_schema_for_tables.<locals>.<listcomp>rJ   )r&   rN   rM   )r>   r   r&   r/   rH   r5   _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.)r^   r`   _get_schemarb   )r>   r   tables_requestedr_   r4   r/   r/   r5   rP      s   


zPowerBIDataset.get_table_infoc                   sJ     |}|du rdS  |}tj fdd|D  I dH   |S )rc   Nrd   c                   s   g | ]}  |qS r/   )_aget_schemar2   r=   r/   r5   r6      s    z2PowerBIDataset.aget_table_info.<locals>.<listcomp>)r^   r`   asynciogatherrb   )r>   r   rf   r_   r/   r=   r5   aget_table_info   s   


zPowerBIDataset.aget_table_infor4   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(rJ   )resultsr   r]   rows'Timeout while getting table info for %sunknown)Error while getting table info for %s: %sN)runr#   
json_to_mdr&   r   rZ   r[   rD   r>   r4   resultrE   r/   r/   r5   re      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 )rl   rm   rJ   rn   Nro   r   r]   rp   rq   rr   rs   )arunr#   ru   r&   r   rZ   r[   rD   rv   r/   r/   r5   rg      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.queryincludeNullsT)queriesimpersonatedUserNameserializerSettings)r   )r>   ry   r/   r/   r5   _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   )jsonrF   timeout  FTokenError: Could not login to PowerBI, please check your credentials.)	rZ   debugrequestspostr?   r   rF   status_coder   )r>   ry   responser/   r/   r5   rt      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.r   r   )total)rF   r   r   Nr   r   )content_type)rZ   r   r'   r   r?   rF   r   r
   statusr   r   aiohttpClientSession)r>   ry   r   response_jsonsessionr/   r/   r5   rx      sD   
,

	.zPowerBIDataset.arun)r+   r,   r-   r   )r-   r   )r-   r%   )r-   rG   N)r   rR   r-   rS   )r_   r   r-   r   )r   r   r-   r   )r   rR   r-   r   )r4   r   r-   rk   )ry   r   r-   rz   )ry   r   r-   r   )#__name__
__module____qualname____doc____annotations__r   r   r   r   r   r#   dictr&   r'   r   model_configr   classmethodr;   propertyr?   rF   rI   rO   rQ   r^   r`   rb   rP   rj   re   rg   r   rt   rx   r/   r/   r/   r5   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   rT   [.]z|  z|
)rY   keysreplacer+   )r   r   	output_mdrF   headerrowrL   r/   r/   r5   ru      s   
ru   r4   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)r4   r/   r/   r5   r1     s   r1   r   )r   r   r   r   r-   r   )r4   r   r-   r   )#r   
__future__r   rh   loggingostypingr   r   r   r   r   r   r	   r   r   r
   r   pydanticr   r   r   r   requests.exceptionsr   	getLoggerr   rZ   getenvr<   azure.core.credentialsr   r   ru   r1   r/   r/   r/   r5   <module>   s(    $
 c