U
    hjM                     @   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mZ ddl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)	BaseModelroot_validator)get_from_dict_or_envz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   I/tmp/pip-unpacked-wheel-9gdii04g/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 k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.   r/   project)r!   r"   r#   r$   r%   r&   r'   r(   r)   r*   r+   r,   r-   r.   r/   r0   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 )
Nr7   r"   r8   r,   r9   r+   r:   r%   )r7   r"   r8   r,   r9   r+   r:   r%   )getr   r   r   r   r   Q   s    zCUList.from_data)r   r   r   r   floatr5   r   r8   r	   r,   r4   r9   boolr+   r:   r%   r   dictr   r   r   r   r   r6   D   s   
r6   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!   r1   r2   initialsr   c                 C   s0   | |d d |d d |d d |d d dS )Nuserr!   r1   r2   r@   )r!   r1   r2   r@   r   r   r   r   r   r   h   s    



zMember.from_dataN)
r   r   r   r   r4   r5   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>|   s     z"Team.from_data.<locals>.<listcomp>rC   r!   r"   )r!   r"   rC   r   )r   r   rC   r   r   r   r   z   s    zTeam.from_dataN)r   r   r   r   r4   r5   r   r   r?   r   r   r   r   r   r   r   rB   r   s   
rB   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 )Zenabledr   )rD   Zfeaturevaluer   r   r   
<dictcomp>   s    z#Space.from_data.<locals>.<dictcomp>featuresr!   r"   rG   )r!   r"   rG   rH   )items)r   r   Z
space_datarH   r   r   r   r      s    
zSpace.from_dataN)r   r   r   r   r4   r5   r   r=   r   r   r   r   r   r   r   r   rF      s   
rF   F)r   	componentfault_tolerantr   c              
   C   sp   zt || W S  tk
rj } z<|rVdt|  dt| d}t| |  W Y 
S |W 5 d}~X Y nX 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   rN   rO   eZwarning_strr   r   r   parse_dict_through_component   s    
rU   )r   rN   r   c                 C   s0   i }t |D ]}|j| k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   rN   output	attributer   r   r   +extract_dict_elements_from_component_fields   s
    
rX   queryrO   r   c              
   C   s^   zt | dfW S  t jk
rX } z(|rDddt| df W Y 
S |W 5 d}~X Y nX 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   )rZ   rO   rT   r   r   r   
load_query   s    r^   )r   keyr   c                 C   sX   || k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 rP   z. Defaulting to first.r!   N)lenrR   rS   )r   r_   r   r   r   fetch_first_id   s
    rb   )urlaccess_tokenrZ   r   c                 C   s(   d|i}t j| ||d}|  | S )zFetch data from a URL.Authorizationheadersparams)requestsr;   raise_for_statusr[   )rc   rd   rZ   rg   responser   r   r   
fetch_data   s    rl   )rd   r   c                 C   s   t  d}t|| }t|dS )zFetch the team id./teamteamsDEFAULT_URLrl   rb   )rd   rc   r   r   r   r   fetch_team_id   s    

rq   )r/   rd   r   c                 C   s,   t  d|  d}t||ddid}t|dS )zFetch the space id./team//spacearchivedfalserZ   rI   ro   )r/   rd   rc   r   r   r   r   fetch_space_id   s    rw   )space_idrd   r   c                 C   s,   t  d|  d}t||ddid}t|dS )zFetch the folder id./space//folderrt   ru   rv   foldersro   )rx   rd   rc   r   r   r   r   fetch_folder_id   s    r|   )rx   r7   rd   r   c                 C   sZ   |rt  d| d}nt  d|  d}t||ddid}|rLd|krL|d S t|dS d	S )
zFetch the list id./folder//listry   rt   ru   rv   r!   listsNro   )rx   r7   rd   rc   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< G d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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.d/Z$eed'd0d1Z%eed'd2d3Z&eed'd4d5Z'eed'd6d7Z(eeed8d9d:Z)dS )=ClickupAPIWrapperzWrapper for Clickup API.Nrd   r/   rx   r7   list_idc                   @   s   e Zd ZdZdS )zClickupAPIWrapper.ConfigZforbidN)r   r   r   extrar   r   r   r   Config  s   r   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   rc   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|krttd|  d|k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   )rh   rd   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)rp   ri   postr[   printr   r   )r   r   r   r   rc   rh   rk   r   r   r   r   get_access_token(  s"    

z"ClickupAPIWrapper.get_access_tokenT)pre)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.rd   ZCLICKUP_ACCESS_TOKENr/   rx   r7   r   )r   rq   rw   r|   r   )r   r   r   r   r   validate_environmentD  s"         z&ClickupAPIWrapper.validate_environment)
input_dictr   c                 C   sn   dg i}|d D ]X}z t |tdd}|d | W q tk
rf } ztd|  W 5 d}~X Y qX q|S )z1Parse appropriate content from the list of teams.rn   FrO   zError parsing a team N)rU   rB   appendrQ   rR   rS   )selfr   parsed_teamsZteamrT   r   r   r   attempt_parse_teamsU  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)re   zContent-Type)
isinstancerd   r   	TypeError)r   rg   r   r   r   get_headersa  s    zClickupAPIWrapper.get_headersc                 C   s   ddiS )Nrt   ru   r   )r   r   r   r   get_default_paramsn  s    z$ClickupAPIWrapper.get_default_paramsc                 C   s2   t  d}tj||  d}| }| |}|S )zGet all teams for the user.rm   )rg   )rp   ri   r;   r   r[   r   )r   rc   rk   r   r   r   r   r   get_authorized_teamsq  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.
        rr   rs   rf   rk   )rp   r   r/   r   ri   r;   r   r   rc   rh   rk   r   r   r   get_folders|  s    zClickupAPIWrapper.get_foldersrY   c           	      C   sn   t |dd\}}|dk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_idsr/   Zinclude_subtasksrf   )	r^   rp   r/   ri   r;   r   r[   rU   r    )	r   rZ   rO   rh   errorrc   rk   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~   rf   rk   )rp   r7   r   ri   r;   r   r   r   r   r   	get_lists  s    zClickupAPIWrapper.get_lists)rZ   r   c                 C   sX   t |dd\}}|dk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   /taskrf   rk   )r^   rp   r   ri   r;   r   )r   rZ   rh   r   rc   rk   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.
        rr   rs   rf   Tr   )	rp   r/   ri   r;   r   r   r[   rU   rF   )r   rc   rk   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 |k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   r^   r   r>   keys)r   rZ   Ztaskrh   r   r   r   r   get_task_attribute  s    
 z$ClickupAPIWrapper.get_task_attributec           	      C   sr   t |dd\}}|dk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   rJ   rg   rh   r[   rk   )r^   rp   r/   r   ri   put)	r   rZ   
query_dictr   rc   rh   rg   payloadrk   r   r   r   update_task  s    zClickupAPIWrapper.update_taskc                 C   s   t |dd\}}|dk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   rk   )
r^   r   r4   typerp   r   
ValueErrorr/   ri   r   )r   rZ   r   r   rA   rc   rg   Zassigne_payloadrh   r   rk   r   r   r   update_task_assignees  s:    
 
z'ClickupAPIWrapper.update_task_assigneesc                 C   s|   t |dd\}}|dk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   r/   )r[   rg   rh   )r^   r   rp   r/   rX   r    r   ri   r   r[   rU   )r   rZ   r   r   r   rc   rh   r   rg   rk   r   r   r   r   create_task  s    
zClickupAPIWrapper.create_taskc                 C   s   t |dd\}}|dkr d|iS | jr,| jn| j}t d| d}t|t}|  }tj|||d}|	 }	t
|	tdd}
d|
kr|
d | _|
S )	z%
        Creates a new list.
        Tr   Nr   r}   r~   r[   rg   r!   )r^   r7   rx   rp   rX   r    r   ri   r   r[   rU   r6   r   )r   rZ   r   r   locationrc   r   rg   rk   r   Zparsed_listr   r   r   create_list"  s    

zClickupAPIWrapper.create_listc           
      C   sx   t |dd\}}|dkr d|iS | j}t d| d}d|d i}|  }tj|||d}| }	d	|	krt|	d	 | _|	S )
z'
        Creates a new folder.
        Tr   Nr   ry   rz   r"   r   r!   )r^   rx   rp   r   ri   r   r[   r   )
r   rZ   r   r   rx   rc   r   rg   rk   r   r   r   r   create_folder:  s     
zClickupAPIWrapper.create_folder)moderZ   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k
r   t| Y S X 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[   dumpsrQ   r   )r   r   rZ   rV   r   r   r   runR  s6    



zClickupAPIWrapper.run)r   )T)*r   r   r   r   rd   r	   r   r5   r/   rx   r7   r   r   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   r     sN   
    	
'r   )F)F)N)+r   r[   rR   Zdataclassesr   r   r   typingr   r   r   r   r	   r
   r   r   ri   Zlangchain_core.pydantic_v1r   r   Zlangchain_core.utilsr   rp   r   r    r6   r?   rB   rF   r>   r=   rU   rX   r   r^   r4   rb   rl   rq   rw   r|   r   r   r   r   r   r   <module>   sX   (+      	