
    _jo,                        S r SSKJr  SSKrSSKJrJrJrJrJ	r	J
r
JrJrJrJr  SSKJrJr  SSKJr  SSKJrJrJrJr  SS	KJrJrJr  \" S
\S9r " S S\\   5      r " S S\5      rg)z Synchronous Research API client.    )annotationsN)
AnyDict	GeneratorGenericLiteralOptionalTypeTypeVarUnionoverload)	BaseModelTypeAdapter   )ResearchBaseClient)ResearchDtoResearchEventListResearchResponseDtoResearchModel)is_pydantic_modelpydantic_to_json_schemastream_sse_eventsT)boundc                  "    \ rS rSrSrSS jrSrg)ResearchTyped%   z%Wrapper for typed research responses.c                   Xl         X l        UR                  U l        UR                  U l        UR                  U l        UR
                  U l        UR                  U l        [        US5      (       a  UR                  U l        [        US5      (       a  UR                  U l	        [        US5      (       a  UR                  U l
        [        US5      (       a  UR                  U l        g g )Neventsoutputcost_dollarserror)researchparsed_outputresearch_idstatus
created_atmodelinstructionshasattrr   r    r!   r"   )selfr#   r$   s      P/home/rurouni/.local/lib/python3.13/site-packages/exa_py/research/sync_client.py__init__ResearchTyped.__init__(   s     *#//oo"--^^
$118X&&"//DK8X&&"//DK8^,, ( 5 5D8W%%!DJ &    )r!   r'   r"   r   r)   r(   r    r$   r#   r%   r&   N)r#   r   r$   r   )__name__
__module____qualname____firstlineno____doc__r-   __static_attributes__ r/   r,   r   r   %   s
    /(r/   r   c                  2   \ rS rSrSr\SS.     SS jj5       r\SS.       SS jj5       r\SS.       S S jj5       rSSS	.       S!S
 jjr\    S"S j5       r\SSS.       S#S jj5       r\SS.       S$S jj5       r\SSS.         S%S jj5       rSSSS.         S&S jjrSSS.     S'S jjr\SSSS.         S(S jj5       r	\SSSS.           S)S jj5       r	SSSSS.           S*S jjr	Sr
g)+ResearchClient;   z(Synchronous client for the Research API.zexa-research-fast)r(   c                   g Nr6   )r+   r)   r(   s      r,   createResearchClient.create>   s     r/   c                   g r;   r6   r+   r)   r(   output_schemas       r,   r<   r=   F        r/   c                   g r;   r6   r?   s       r,   r<   r=   O   rA   r/   N)r(   r@   c                   UUS.nUb#  [        U5      (       a  [        U5      US'   OX4S'   U R                  SSUS9n[        [        5      nUR                  U5      $ )a  Create a new research request.

Args:
    instructions (str): The research instructions describing what to research.
    model (str): The model to use ('exa-research-fast', 'exa-research', or 'exa-research-pro').
    output_schema (dict): Optional JSON schema for structured output format.

Returns:
    The created research object with a unique research_id.

Examples:
    from exa_py import Exa
    import os

    exa = Exa(os.environ["EXA_API_KEY"])

    # Create a simple research task
    instructions = "What is the latest valuation of SpaceX?"
    schema = {
        "type": "object",
        "properties": {
            "valuation": {"type": "string"},
            "date": {"type": "string"},
            "source": {"type": "string"}
        }
    }

    task = exa.research.create(
        instructions=instructions,
        output_schema=schema
    )

    print(f"Task created with ID: {task.research_id}")
)r)   r(   outputSchema POST)methoddata)r   r   requestr   r   validate_python)r+   r)   r(   r@   payloadresponseadapters          r,   r<   r=   X   sk    T )

 $ //*A-*P'*7'<<6<@k*&&x00r/   c                    g r;   r6   )r+   r%   s     r,   getResearchClient.get   s     r/   F)streamr   c                   g r;   r6   r+   r%   rQ   r   s       r,   rO   rP      rA   r/   r   c                   g r;   r6   rS   s       r,   rO   rP      s     03r/   c                   g r;   r6   )r+   r%   rQ   r   r@   s        r,   rO   rP      s     r/   )rQ   r   r@   c                  0 nU(       d  SUS'   U(       a  SUS'   O$SUS'   Ub  [        U5      R                  5       US'   U(       a   U R                  SU 3SUSS	9n[        U5      $ U R                  SU 3SUS
9n[	        [
        5      nUR                  U5      nU(       a  [        US5      (       a  UR                  (       a   UR                  R                  (       a&  UR                  UR                  R                  5      n	O:SSKn
U
R                  UR                  R                  5      nUR                  U5      n	[        X5      $ U$ ! [         a    Us $ f = f)aZ  Get a research request by ID.

Args:
    research_id (str): The unique identifier of the research task.
    stream (bool): Whether to stream events as they occur.
    events (bool): Whether to include events in the response.
    output_schema (Type[BaseModel]): Optional Pydantic model for typed output validation.

Returns:
    Research object with status and results.

Examples:
    # Get a research task by ID
    task_id = "your-task-id-here"
    task = exa.research.get(task_id)

    print(f"Task status: {task.status}")
    if task.status == "completed":
        print(f"Results: {task.output}")
falserQ   truer   N/GETT)rG   paramsrQ   rG   r\   r    r   )strlowerrI   r   r   r   rJ   r*   r    parsedmodel_validatejsonloadscontentr   	Exception)r+   r%   rQ   r   r@   r\   rL   rM   r#   r`   rb   parsed_datas               r,   rO   rP      sG   8 &F8#)x %F8!#&v;#4#4#6x ||K=!%t $ H %X..||a}$5eF|SH!+.G..x8H8!<!<$--!.!=!=hoo>T>T!U#&*jj1H1H&I!.!=!=k!J(::
 O	 ! $#O$s   BE EE)cursorlimitc               r    U R                  X5      nU R                  SSUS9n[        R                  " U5      $ )a  List research requests.

Args:
    cursor (str): Pagination cursor from a previous response.
    limit (int): Maximum number of results to return.

Returns:
    List of research objects with pagination info.

Examples:
    # List all research tasks
    response = exa.research.list()
    print(f"Found {len(response.data)} tasks")

    # List with pagination
    response = exa.research.list(limit=10)
    if response.has_more:
        next_page = exa.research.list(cursor=response.next_cursor)
rE   r[   r]   )build_pagination_paramsrI   r   ra   )r+   rg   rh   r\   rL   s        r,   listResearchClient.list   s9    2 --f<<<5<@&55h??r/     i'	 )poll_interval
timeout_msr   c                   g r;   r6   )r+   r%   rn   ro   r   s        r,   poll_until_finished"ResearchClient.poll_until_finished  s     r/   c                   g r;   r6   )r+   r%   rn   ro   r   r@   s         r,   rq   rr     s     r/   )rn   ro   r   r@   c          	        US-  nUS-  nSn[         R                   " 5       n	Sn
  U(       a  U R                  XUS9nOU R                  XS9nSn
[        US5      (       a  UR                  OSnUS;   a  U$  [         R                   " 5       U	-
  U:  a  [        SU SU S35      e[         R                  " U5        M  ! [         a(  nU
S	-  n
X:  a  [        S
U SU SU 35      e SnANsSnAff = f)af  Poll until research is finished.

Args:
    research_id (str): The unique identifier of the research task.
    poll_interval (int): Milliseconds between polling attempts.
    timeout_ms (int): Maximum time to wait in milliseconds before timing out.
    events (bool): Whether to include events in the response.
    output_schema (Type[BaseModel]): Optional Pydantic model for typed output validation.

Returns:
    Completed research object with results.

Raises:
    TimeoutError: If research doesn't complete within timeout.
    RuntimeError: If polling fails too many times.

Examples:
    # Create and poll a task until completion
    task = exa.research.create(
        instructions="Get information about Paris, France",
        output_schema={
            "type": "object",
            "properties": {
                "name": {"type": "string"},
                "population": {"type": "string"},
                "founded_date": {"type": "string"}
            }
        }
    )

    # Poll until completion
    result = exa.research.poll_until_finished(task.research_id)
    print(f"Research complete: {result.output}")
rm      r   )r   r@   rT   r&   N)	completedfailedcanceledr   zPolling failed z times in a row for research z: z	Research z did not complete within ms)timerO   r*   r&   re   RuntimeErrorTimeoutErrorsleep)r+   r%   rn   ro   r   r@   poll_interval_sectimeout_secmax_consecutive_failures
start_timeconsecutive_failuresresultr&   es                 r,   rq   rr   $  s8   V *D0 4'#$ YY[
  !XX#- & F "XXkXAF'($ +2&(*C*C@@!M A yy{Z'+5"},Ej\QST  JJ();    $)$'C&)*B)C D((3}Bqc;  Ds   AB= =
C/C**C/r6   )r)   r^   r(   r   returnr   )r)   r^   r(   r   r@   zDict[str, Any]r   r   )r)   r^   r(   r   r@   Type[T]r   r   )r)   r^   r(   r   r@   z0Optional[Union[Dict[str, Any], Type[BaseModel]]]r   r   )r%   r^   r   r   )r%   r^   rQ   Literal[False]r   boolr   r   )r%   r^   rQ   zLiteral[True]r   zOptional[bool]r   z$Generator[ResearchEvent, None, None])
r%   r^   rQ   r   r   r   r@   r   r   ResearchTyped[T])
r%   r^   rQ   r   r   r   r@   Optional[Type[BaseModel]]r   zGUnion[ResearchDto, ResearchTyped, Generator[ResearchEvent, None, None]])rg   zOptional[str]rh   zOptional[int]r   r   )
r%   r^   rn   intro   r   r   r   r   r   )r%   r^   rn   r   ro   r   r   r   r@   r   r   r   )r%   r^   rn   r   ro   r   r   r   r@   r   r   z!Union[ResearchDto, ResearchTyped])r0   r1   r2   r3   r4   r   r<   rO   rk   rq   r5   r6   r/   r,   r8   r8   ;   sY   2
  3	  	
 
  
  3	  	
 & 
  
  3	  	
  
   3JN61 61 	61
 H61 
61p  
 
 
 "' 	
  
   "&33 	3
 3 
.3 3 
 "' 	
   
  37>> 	>
 > 1> 
Q>F !%#	@ @ 	@
 
!@: 
 "  	
   
  
 "  	
    
  " 37N*N* 	N*
 N* N* 1N* 
+N* N*r/   r8   ) r4   
__future__r   rz   typingr   r   r   r   r   r	   r
   r   r   r   pydanticr   r   baser   modelsr   r   r   r   utilsr   r   r   r   r   r8   r6   r/   r,   <module>r      sf    & "    , $   Cy!(GAJ (,w*' w*r/   