a
    bgM                     @   s  d Z ddlZddlZddlmZmZmZ ddlmZm	Z	m
Z
mZmZmZmZmZ ddlZddlmZ ddlmZmZmZ dZeG dd	 d	ZeG d
d deZeG dd deZeG dd deZeG dd deZeG dd deZd2eee ee	dddZ eee edddZ!d3e"eeee	 ee" f dddZ#ee"ee$ ddd Z%d4e"e"ee ed!d"d#Z&e"ee$ d$d%d&Z'e$e"ee$ d'd(d)Z(e$e"ee$ d*d+d,Z)e$e$e"ee$ d-d.d/Z*G d0d1 d1eZ+dS )5zUtil that calls clickup.    N)asdict	dataclassfields)AnyDictListMappingOptionalTupleTypeUnion)get_from_dict_or_env)	BaseModel
ConfigDictmodel_validatorzhttps://api.clickup.com/api/v2c                   @   s,   e Zd ZdZeeeef d dddZdS )	ComponentzBase class for all components.datareturnc                 C   s
   t  d S )N)NotImplementedErrorclsr    r   s/var/www/html/cobodadashboardai.evdpl.com/venv/lib/python3.9/site-packages/langchain_community/utilities/clickup.py	from_data   s    zComponent.from_dataN)	__name__
__module____qualname____doc__classmethodr   strr   r   r   r   r   r   r      s   r   c                   @   s   e Zd ZU dZeed< eed< eed< eed< eed< eed< eed< eed	< eeee	f  ed
< eeee	f  ed< e
e ed< e
e ed< e
e ed< eed< eed< eed< eeee	f d dddZdS )TaskzClass for a task.idnametext_contentdescriptionstatus
creator_idcreator_usernamecreator_email	assigneeswatchersprioritydue_date
start_datepointsteam_id
project_idr   c                 C   s   |d d u rd n
|d d }| |d |d |d |d |d d |d d |d d |d d	 |d
 |d ||d |d |d |d |d d dS )Nr,   r"   r#   r$   r%   r&   Zcreatorusernameemailr*   r+   r-   r.   r/   r0   project)r"   r#   r$   r%   r&   r'   r(   r)   r*   r+   r,   r-   r.   r/   r0   r1   r   )r   r   r,   r   r   r   r   -   s&    




zTask.from_dataN)r   r   r   r   int__annotations__r    r   r   r   r	   r   r   r   r   r   r   r!      s&   
r!   c                   @   s   e Zd ZU dZeed< eed< dZee ed< dZ	ee
 ed< dZee ed< dZee
 ed< dZee
 ed	< dZee ed
< eed dddZdS )CUListzComponent class for a list.	folder_idr#   Ncontentr-   due_date_timer,   assigneer&   r   c                 C   sD   | |d |d | d| d| d| d| d| dd	S )
Nr8   r#   r9   r-   r:   r,   r;   r&   )r8   r#   r9   r-   r:   r,   r;   r&   )getr   r   r   r   r   Q   s    zCUList.from_data)r   r   r   r   floatr6   r    r9   r	   r-   r5   r:   boolr,   r;   r&   r   dictr   r   r   r   r   r7   D   s   
r7   c                   @   sF   e Zd ZU dZeed< eed< eed< eed< eed dddZ	d	S )
MemberzComponent class for a member.r"   r2   r3   initialsr   c                 C   s0   | |d d |d d |d d |d d dS )Nuserr"   r2   r3   rA   )r"   r2   r3   rA   r   r   r   r   r   r   h   s    



zMember.from_dataN)
r   r   r   r   r5   r6   r    r   r   r   r   r   r   r   r@   _   s   
r@   c                   @   sB   e Zd ZU dZeed< eed< ee ed< e	e
d dddZdS )	TeamzComponent class for a team.r"   r#   membersr   c                 C   s(   dd |d D }| |d |d |dS )Nc                 S   s   g | ]}t |qS r   )r@   r   ).0Zmember_datar   r   r   
<listcomp>|       z"Team.from_data.<locals>.<listcomp>rD   r"   r#   )r"   r#   rD   r   )r   r   rD   r   r   r   r   z   s    zTeam.from_dataN)r   r   r   r   r5   r6   r    r   r@   r   r   r   r   r   r   r   rC   r   s   
rC   c                   @   sV   e Zd ZU dZeed< eed< eed< eee	f ed< e
eee	f d dddZd	S )
SpacezComponent class for a space.r"   r#   privateenabled_featuresr   c                 C   s>   |d d }dd |d   D }| |d |d |d |d	S )
Nspacesr   c                 S   s   i | ]\}}|d  r||qS )enabledr   )rE   featurevaluer   r   r   
<dictcomp>   s   z#Space.from_data.<locals>.<dictcomp>featuresr"   r#   rI   )r"   r#   rI   rJ   )items)r   r   Z
space_datarJ   r   r   r   r      s    
zSpace.from_dataN)r   r   r   r   r5   r6   r    r>   r   r   r   r   r   r   r   r   rH      s   
rH   F)r   	componentfault_tolerantr   c              
   C   sv   zt || W S  typ } zH|rXdt|  dt| d}t| | W  Y d}~S |W Y d}~n
d}~0 0 dS )a  Parse a dictionary by creating
    a component and then turning it back into a dictionary.

    This helps with two things
    1. Extract and format data from a dictionary according to schema
    2. Provide a central place to do this in a fault-tolerant way

    z(Error encountered while trying to parse
: z'
 Falling back to returning input data.N)r   r   	Exceptionr    warningswarn)r   rR   rS   eZwarning_strr   r   r   parse_dict_through_component   s    
rY   )r   rR   r   c                 C   s0   i }t |D ]}|j| v r| |j ||j< q|S )a"  Extract elements from a dictionary.

    Args:
        data: The dictionary to extract elements from.
        component: The component to extract elements from.

    Returns:
        A dictionary containing the elements from the input dictionary that are also
        in the component.
    )r   r#   )r   rR   output	attributer   r   r   +extract_dict_elements_from_component_fields   s
    
r\   queryrS   r   c              
   C   sd   zt | dfW S  t jy^ } z4|rFddt| dfW  Y d}~S |W Y d}~n
d}~0 0 dS )aD  Parse a JSON string and return the parsed object.

    If parsing fails, returns an error message.

    :param query: The JSON string to parse.
    :return: A tuple containing the parsed object or None and an error message or None.

    Exceptions:
        json.JSONDecodeError: If the input is not a valid JSON string.
    Nz5Input must be a valid JSON. Got the following error: z". 
"Please reformat and try again.)jsonloadsJSONDecodeErrorr    )r^   rS   rX   r   r   r   
load_query   s    rb   )r   keyr   c                 C   sX   || v rTt | | dkrTt | | dkrDtd| d| |  d | | d d S dS )z%Fetch the first id from a dictionary.r      zFound multiple rT   z. Defaulting to first.r"   N)lenrV   rW   )r   rc   r   r   r   fetch_first_id   s
    rf   )urlaccess_tokenr^   r   c                 C   s(   d|i}t j| ||d}|  | S )zFetch data from a URL.Authorizationheadersparams)requestsr<   raise_for_statusr_   )rg   rh   r^   rk   responser   r   r   
fetch_data   s    rp   )rh   r   c                 C   s   t  d}t|| }t|dS )zFetch the team id./teamteamsDEFAULT_URLrp   rf   )rh   rg   r   r   r   r   fetch_team_id   s    

ru   )r0   rh   r   c                 C   s,   t  d|  d}t||ddid}t|dS )zFetch the space id./team//spacearchivedfalser^   rK   rs   )r0   rh   rg   r   r   r   r   fetch_space_id   s    r{   )space_idrh   r   c                 C   s,   t  d|  d}t||ddid}t|dS )zFetch the folder id./space//folderrx   ry   rz   foldersrs   )r|   rh   rg   r   r   r   r   fetch_folder_id   s    r   )r|   r8   rh   r   c                 C   sZ   |rt  d| d}nt  d|  d}t||ddid}|rLd|v rL|d S t|dS d	S )
zFetch the list id./folder//listr}   rx   ry   rz   r"   listsNrs   )r|   r8   rh   rg   r   r   r   r   fetch_list_id  s    r   c                   @   s  e Zd ZU dZdZee ed< dZee ed< dZ	ee ed< dZ
ee ed< dZee ed< edd	Zed<eeedddZeeeeee dddZeddeeedddZeeeee f dddZeeeeef f dddZedddZeeef dddZedd d!Zd=eeed#d$d%Z edd&d'Z!eed(d)d*Z"edd+d,Z#eed(d-d.Z$eed(d/d0Z%eed(d1d2Z&eed(d3d4Z'eed(d5d6Z(eed(d7d8Z)eeed9d:d;Z*dS )>ClickupAPIWrapperzWrapper for Clickup API.Nrh   r0   r|   r8   list_idZforbid)extrahttps://google.com)oauth_client_idredirect_urir   c                 C   s   d| }| d| S )z"Get the URL to get an access code.z&https://app.clickup.com/api?client_id=z&redirect_uri=r   )r   r   r   rg   r   r   r   get_access_code_url!  s    
z%ClickupAPIWrapper.get_access_code_url)r   oauth_client_secretcoder   c                 C   s|   t  d}|||d}tj||d}| }d|vrttd|  d|v rp|d dkrpt|}tdd	|  d
S |d S )zGet the access token.z/oauth/token)Z	client_idZclient_secretr   )rl   rh   zError: ZECODEZ	OAUTH_014z4You already used this code once. Generate a new one.z1Our best guess for the url to get a new code is:
N)rt   rm   postr_   printr   r   )r   r   r   r   rg   rl   ro   r   r   r   r   get_access_token)  s"    

z"ClickupAPIWrapper.get_access_tokenbefore)mode)valuesr   c                 C   sl   t |dd|d< t|d |d< t|d |d |d< t|d |d |d< t|d |d |d |d< |S )z?Validate that api key and python package exists in environment.rh   ZCLICKUP_ACCESS_TOKENr0   r|   r8   r   )r   ru   r{   r   r   )r   r   r   r   r   validate_environmentE  s    z&ClickupAPIWrapper.validate_environment)
input_dictr   c                 C   sp   dg i}|d D ]Z}z t |tdd}|d | W q tyh } ztd|  W Y d}~qd}~0 0 q|S )z1Parse appropriate content from the list of teams.rr   FrS   zError parsing a team N)rY   rC   appendrU   rV   rW   )selfr   parsed_teamsZteamrX   r   r   r   attempt_parse_teamsW  s    (z%ClickupAPIWrapper.attempt_parse_teams)r   c                 C   s2   t | jtstd| j dt| jdd}|S )z Get the headers for the request.zAccess Token: z, must be str.zapplication/json)ri   zContent-Type)
isinstancerh   r    	TypeError)r   rk   r   r   r   get_headersc  s    zClickupAPIWrapper.get_headersc                 C   s   ddiS )Nrx   ry   r   )r   r   r   r   get_default_paramsp  s    z$ClickupAPIWrapper.get_default_paramsc                 C   s2   t  d}tj||  d}| }| |}|S )zGet all teams for the user.rq   )rk   )rt   rm   r<   r   r_   r   )r   rg   ro   r   r   r   r   r   get_authorized_teamss  s
    

z&ClickupAPIWrapper.get_authorized_teamsc                 C   s<   t  dt| j d }|  }tj||  |d}d|iS )z3
        Get all the folders for the team.
        rv   rw   rj   ro   )rt   r    r0   r   rm   r<   r   r   rg   rl   ro   r   r   r   get_folders~  s    zClickupAPIWrapper.get_foldersTr]   c           	      C   sn   t |dd\}}|du r d|iS t d|d  }d| jdd}tj||  |d	}| }t|t|d}|S )
z+
        Retrieve a specific task.
        Tr   NError/task/task_idtruecustom_task_idsr0   Zinclude_subtasksrj   )	rb   rt   r0   rm   r<   r   r_   rY   r!   )	r   r^   rS   rl   errorrg   ro   r   Zparsed_taskr   r   r   get_task  s    zClickupAPIWrapper.get_taskc                 C   s6   t  d| j d}|  }tj||  |d}d|iS )z*
        Get all available lists.
        r   r   rj   ro   )rt   r8   r   rm   r<   r   r   r   r   r   	get_lists  s    zClickupAPIWrapper.get_lists)r^   r   c                 C   sX   t |dd\}}|du r d|iS t d|d  d}|  }tj||  |d}d	|iS )
z7
        Query tasks that match certain fields
        Tr   Nr   /list/r   /taskrj   ro   )rb   rt   r   rm   r<   r   )r   r^   rl   r   rg   ro   r   r   r   query_tasks  s    zClickupAPIWrapper.query_tasksc                 C   sD   t  d| j d}tj||  |  d}| }t|tdd}|S )z.
        Get all spaces for the team.
        rv   rw   rj   Tr   )	rt   r0   rm   r<   r   r   r_   rY   rH   )r   rg   ro   r   Zparsed_spacesr   r   r   
get_spaces  s    zClickupAPIWrapper.get_spacesc                 C   sn   | j |dd}t|dd\}}t|ts0d|iS |d |vrZdd|d  d|  diS |d ||d  iS ):
        Update an attribute of a specified task.
        Tr   r   attribute_namezattribute_name = z was not 
found in task keys z.. Please call again with one of the key names.)r   rb   r   r?   keys)r   r^   taskrl   r   r   r   r   get_task_attribute  s    
z$ClickupAPIWrapper.get_task_attributec           	      C   sr   t |dd\}}|du r d|iS t d|d  }d| jdd}|  }|d	 |d
 i}tj||||d}d|iS )r   Tr   Nr   r   r   r   r   r   rN   rk   rl   r_   ro   )rb   rt   r0   r   rm   put)	r   r^   
query_dictr   rg   rl   rk   payloadro   r   r   r   update_task  s    zClickupAPIWrapper.update_taskc                 C   s   t |dd\}}|du r d|iS |d D ]*}t|ts(dd| dt| i  S q(t d|d	  }|  }|d
 dkr|d g d}n2|d
 dkrg |d d}ntd|d
  ddd| jdd}d|i}	tj	||||	d}
d|
iS )z>
        Add or remove assignees of a specified task.
        Tr   Nr   Zusersz3All users must be integers, not strings!
"Got user z	 if type r   r   Z	operationadd)r   remr   zInvalid operation (z). zValid options ['add', 'rem'].r   r   r*   r   ro   )
rb   r   r5   typert   r   
ValueErrorr0   rm   r   )r   r^   r   r   rB   rg   rk   Zassigne_payloadrl   r   ro   r   r   r   update_task_assignees  s8    

z'ClickupAPIWrapper.update_task_assigneesc                 C   s|   t |dd\}}|du r d|iS | j}t d| d}d| jd}t|t}|  }tj||||d	}	|		 }
t
|
tddS )
z%
        Creates a new task.
        Tr   Nr   r   r   r   )r   r0   )r_   rk   rl   )rb   r   rt   r0   r\   r!   r   rm   r   r_   rY   )r   r^   r   r   r   rg   rl   r   rk   ro   r   r   r   r   create_task  s    
zClickupAPIWrapper.create_taskc                 C   s   t |dd\}}|du r d|iS | jr,| jn| j}t d| d}t|t}|  }tj|||d}|	 }	t
|	tdd}
d|
v r|
d | _|
S )	z%
        Creates a new list.
        Tr   Nr   r   r   r_   rk   r"   )rb   r8   r|   rt   r\   r!   r   rm   r   r_   rY   r7   r   )r   r^   r   r   locationrg   r   rk   ro   r   Zparsed_listr   r   r   create_list$  s    

zClickupAPIWrapper.create_listc           
      C   sx   t |dd\}}|du r d|iS | j}t d| d}d|d i}|  }tj|||d}| }	d	|	v rt|	d	 | _|	S )
z'
        Creates a new folder.
        Tr   Nr   r}   r~   r#   r   r"   )rb   r|   rt   r   rm   r   r_   r   )
r   r^   r   r   r|   rg   r   rk   ro   r   r   r   r   create_folder<  s    
zClickupAPIWrapper.create_folder)r   r^   r   c                 C   s  |dkr|  |}n|dkr(| |}n|dkr:|  }n|dkrN| |}n|dkrb| |}n|dkrv| |}nn|dkr|  }n\|dkr|  }nJ|d	kr|  }n8|d
kr| 	|}n$|dkr| 
|}ndd| di}zt|W S  ty   t| Y S 0 dS )zRun the API.r   r   Z	get_teamsr   r   r   r   r   r   r   r   Z	ModeErrorzGot unexpected mode .N)r   r   r   r   r   r   r   r   r   r   r   r_   dumpsrU   r    )r   r   r^   rZ   r   r   r   runT  s6    



zClickupAPIWrapper.run)r   )T)+r   r   r   r   rh   r	   r    r6   r0   r|   r8   r   r   Zmodel_configr   r   r   r   r   r   r   r?   r   r   r   r   bytesr   r   r   r   r>   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r     sN   
 	
'r   )F)F)N),r   r_   rV   dataclassesr   r   r   typingr   r   r   r   r	   r
   r   r   rm   Zlangchain_core.utilsr   Zpydanticr   r   r   rt   r   r!   r7   r@   rC   rH   r?   r>   rY   r\   r    rb   r5   rf   rp   ru   r{   r   r   r   r   r   r   r   <module>   sP   (+ 
 	