
    "<i"                     D   d 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mZ ddlmZ ddlmZ ddlm	Z ddlm
Z dd	lmZ dd
lmZ ddlmZ ddlmZmZ ddlmZ ddlmZmZmZm Z m!Z!m"Z" ddl#m$Z$m%Z%  ee&          Z' edee          Z( edee          Z) ede
e          Z* edee          Z+ edee          Z, edee          Z- edee          Z. ede	e          Z/de0e1ef         de2e         fdZ3 G d dee(e*e)e+e,e-e.e/f                   Z4ddgZ5dS ) zHOpenAPI parsing logic for converting OpenAPI specs to HTTPRoute objects.    )AnyGenericTypeVar)OpenAPI	Operation	ParameterPathItem	ReferenceRequestBodyResponseSchema)r   )r   )r   )r	   )r
   )r   )r   )r   )	BaseModelValidationError)
get_logger   )	HTTPRoute
JsonSchemaParameterInfoParameterLocationRequestBodyInfoResponseInfo)_combine_schemas_and_map_params_replace_ref_with_defsTOpenAPITSchema
TReference
TParameterTRequestBody	TResponse
TOperation	TPathItemopenapi_dictreturnc                 P   |                      dd          }	 |                    d          rt          j        |           }t                              d|j                    t          |t          t          t          t          t          t          t          |	  	        }|                                S t!          j        |           }t                              d|j                    t          |t"          t$          t&          t(          t*          t,          t.          |	  	        }|                                S # t0          $ rf}t                              d|            |                                }t                              d|            t7          d|           |d	}~ww xY w)
z
    Parses an OpenAPI schema dictionary into a list of HTTPRoute objects
    using the openapi-pydantic library.

    Supports both OpenAPI 3.0.x and 3.1.x versions.
    openapi z3.0z0Successfully parsed OpenAPI 3.0 schema version: z0Successfully parsed OpenAPI 3.1 schema version: z"OpenAPI schema validation failed: zValidation errors: zInvalid OpenAPI schema: N)get
startswith
OpenAPI_30model_validateloggerdebugr%   OpenAPIParserReference_30	Schema_30Parameter_30RequestBody_30Response_30Operation_30PathItem_30parser   r
   r   r   r   r   r   r	   r   errorerrors
ValueError)r"   openapi_version
openapi_30parser
openapi_31eerror_detailss          /Users/kimhansen/Desktop/03 Workspace/ceo-agents/chl-effectiveness/mcp-servers/whoop/.venv/lib/python3.11/site-packages/fastmcp/utilities/openapi/parser.pyparse_openapi_to_http_routesr@   7   s    #&&y"55O)L%%e,, #	"#2<@@JLLW:CUWW   #
 
F <<>>! !/==JLLW:CUWW   #
 
F <<>>! L L L=!==>>>

:=::;;;CMCCDD!K	Ls    BD5 1BD5 5
F%?A!F  F%c                      e Zd ZdZdedee         dee         dee         dee	         dee
         dee         d	ee         d
efdZdedefdZdedefdZdedefdZ	 	 d(dee         dz  dee         dz  dee         fdZdededz  fdZdedefdZdeeef         deeef         dz  fdZdeeef         dz  deeef         fdZ 	 d)dedeeef         d e!e         dz  de!e         fd!Z"d"ee         d#edz  deeef         deeef         fd$Z#d%eeef         deeef         deeef         fd&Z$dee%         fd'Z&dS )*r-   z[Unified parser for OpenAPI schemas with generic type parameters to handle both 3.0 and 3.1.r%   reference_cls
schema_clsparameter_clsrequest_body_clsresponse_clsoperation_clspath_item_clsr9   c
                     || _         || _        || _        || _        || _        || _        || _        || _        |	| _        dS )z?Initialize the parser with the OpenAPI schema and type classes.N)	r%   rB   rC   rD   rE   rF   rG   rH   r9   )
selfr%   rB   rC   rD   rE   rF   rG   rH   r9   s
             r?   __init__zOpenAPIParser.__init__{   sP     *$* 0(**.    param_inr#   c                 N    |dv r|S t                               d| d           dS )z@Convert string parameter location to our ParameterLocation type.)pathqueryheadercookiezUnknown parameter location: z, defaulting to 'query'rP   )r+   warning)rJ   rM   s     r?   _convert_to_parameter_locationz,OpenAPIParser._convert_to_parameter_location   s6    <<<OWhWWWXXXwrL   itemc                 `   t          || j                  r|j        }t          |t                    s|S 	 |                    d          st          d|           |                    d                              d          }| j        }|D ]1}|	                                r+t          |t                    r|t          |                   }nt          |t                    r||j        j        v rt          ||d          }n|j        r||j        v r|j        |         }n|dk    rt#          |d          r|j        }nft#          ||          rt          ||d          }nDd}nAt          |t&                    r|                    |          }nt          d| d| d          |t          d	| d
| d          3t          || j                  r|                     |          S |S # t,          t.          t0          t2          t
          f$ r}t          d| d|           |d}~ww xY w|S )z.Resolves a reference to its target definition.z#/z/External or non-local reference not supported: /N
componentszCannot traverse part 'z' in reference ''zReference part 'z' not found in path 'zFailed to resolve reference '': )
isinstancerB   refstrr(   r8   stripsplitr%   isdigitlistintr   	__class__model_fieldsgetattrmodel_extrahasattrrX   dictr'   _resolve_refAttributeErrorKeyError
IndexError	TypeError)rJ   rU   ref_strpartstargetpartr=   s          r?   ri   zOpenAPIParser._resolve_ref   s   dD.// 1	YhGgs++ ,Y))$// $S'SS    d++11#66!  D||~~ *VT*B*B !'D		!2#FI66 6#3#@@@%,VT4%@%@FF#/ 	.DF<N4N4N%+%7%=FF  $|338U8U3)/):!(!6!6 .)0t)D)D)-#FD11 !'D!1!1(UTUU7UUU   ~(TtTT'TTT   & fd&899 5,,V444"Hj)ZP Y Y Y !P!P!PQ!P!PQQWXXY s   F4G- +G- -#H+H&&H+
schema_objc                 0   	 |                      |          }t          || j                  r|                    ddd          }nEt          |t                    r|}n-t
                              dt          |           d           i }t          |          }|S # t          $ r=}dt          |          v r t
                              d| d	           i cY d
}~S d
}~wt          $ r+}t
                              d| d	           i cY d
}~S d
}~ww xY w)z1Resolves a schema and returns it as a dictionary.jsonT)modeby_aliasexclude_nonez%Expected Schema after resolving, got z. Returning empty dict.-External or non-local reference not supportedz"Failed to extract schema as dict: Fexc_infoN)ri   r[   rC   
model_dumprh   r+   rS   typer   r8   r]   r6   	Exception)rJ   rr   resolved_schemaresultr=   s        r?   _extract_schema_as_dictz%OpenAPIParser._extract_schema_as_dict   sX   	"//
;;O/4?;; (33$T 4   OT22 (jD<Q<Qjjj    ,F33FM 	 	 	>#a&&HHLLAaAAELRRRIIIIII 	 	 	LLAaAAELRRRIIIIII	s0   BB 
D%2CDD* D
DDNoperation_paramspath_item_paramsc                 R   g }i }|pg |pg z   }|D ]}	 |                      |          }t          || j                  s,t                              dt          |           d           Z|j        }ddlm}	 t          ||	          r|j	        n|}
| 
                    |
          }|j        }|j        |
f}||v rd||<   i }|ra|                     |          }|                      |          }t          || j                  s!t          |d          r|j        
|j        |d<   nt          |d          r|j        rt%          t'          |j                                                  d          }|r~t          |d	          rn|j        rg|j        }|                     |          }|                      |          }t          || j                  s!t          |d          r|j        
|j        |d<   t-          |d
d          }t-          |dd          }t/          |j        ||j        ||j        ||          }|                    |           =# t6          $ rM}t-          |dt-          |dd                    }t                              d| d| d           Y d}~d}~ww xY w|S )z<Extract and resolve parameters from operation and path item.z(Expected Parameter after resolving, got z. Skipping.r   )EnumTdefaultNcontentmedia_type_schemaexplodestyle)namelocationrequiredschemadescriptionr   r   r   r\   unknownzFailed to extract parameter 'rZ   Fry   )ri   r[   rD   r+   rS   r|   rM   enumr   valuerT   param_schemar   r   rB   rg   r   r   nextitervaluesr   re   r   r   r   appendr}   r6   )rJ   r   r   extracted_paramsseen_params
all_paramsparam_or_ref	parameterrM   r   param_in_strparam_locationparam_schema_obj	param_keyparam_schema_dictr~   first_media_typemedia_schemaresolved_media_schemar   r   
param_infor=   
param_names                           r?   _extract_parametersz!OpenAPIParser._extract_parameters   s    13  	 ',"1A1GRH
& S	 S	LR --l;;	!)T-?@@ NN_4	??___    %-%%%%%% '14&@&@NHNNh  "&!D!D\!R!R#,#9  '^\:	++)-I& %'!# Y(,(D(DEU(V(V% '+&7&78H&I&IO&8JKKO#OY??O ,3?7F7N))4Y	22 Yy7H Y'+D1B1I1I1K1K,L,Ld'S'S$(Y#$46IJJY ->Y
 (8'I,0,H,H,V,V) 150A0A,0O0O- *+@$BT U UY '(=y I IY !6 = I;P;X-i8 ")Y==	7D99 +"+&/, ) 5#  
 !''
3333   $ &',y*Q*Q 
 FJFF1FFQV         	  s'   AI*AI:FI
J$AJJ$request_body_or_refc                    |sdS 	 |                      |          }t          || j                  s-t                              dt          |           d           dS t          |j        |j                  }t          |d          r|j
        r|j
                                        D ]\  }}|rt          |d          r|j        r	 |                     |j                  }||j        |<   D# t          $ r<}dt!          |          v r t                              d| d	|            Y d}~d}~wt$          $ r*}t                              d| d	|            Y d}~d}~ww xY w|S # t          $ rP}dt!          |          v r t'          |d
d          }t                              d| d	| d           Y d}~dS d}~wt$          $ r>}t'          |d
d          }t                              d| d	| d           Y d}~dS d}~ww xY w)z-Extract and resolve request body information.Nz*Expected RequestBody after resolving, got z. Returning None.)r   r   r   r   rx   )Failed to extract schema for media type 'rZ   r\   r   z Failed to extract request body 'Fry   )ri   r[   rE   r+   rS   r|   r   r   r   rg   r   itemsr   r   content_schemar8   r]   r6   r}   re   )	rJ   r   request_bodyrequest_body_infomedia_type_strmedia_type_objschema_dictr=   ref_names	            r?   _extract_request_bodyz#OpenAPIParser._extract_request_bodyS  s   " 	4;	,,-@AALlD,ABB flASASfff   t !0%.(4! ! ! |Y// L4H 6B6J6P6P6R6R  2NN&#N4GHH +<
*.*F*F . @+ +K !, .<^LL  *   NRU !S S     !&"LL bN b b_` b b         )   "LL bN b b_` b b       
 %$ 	 	 	>#a&&HH2E9EEHLLC8CCCCe     44444 	 	 	2E9EEHLLC8CCCCe     44444	sh   AE* A)E* $C,+E* ,
E$62D-(E* -E$: EE* E$$E* *
H
4AF??H
3HH
status_codec                     	 t          |          }d|cxk    odk     nc S # t          t          f$ r |                                dv cY S w xY w)z>Check if a status code represents a successful response (2xx).   i,  )r   2xx)rb   r8   rm   lower)rJ   r   code_ints      r?   _is_success_status_codez%OpenAPIParser._is_success_status_code  st    	=;''H(((((S(((((I& 	= 	= 	=$$&&*<<<<<	=s   ! 'A
Aoperation_responsesc                     |sdS g d}|D ]}||v r|||         fc S |                                 D ] \  }}|                     |          r||fc S !dS )zTGet the primary success response for an MCP tool. We only need one success response.N)200201202204207)r   r   )rJ   r   priority_codescoder   resp_or_refs         r?   _get_primary_success_responsez+OpenAPIParser._get_primary_success_response  s     # 	4 =<< # 	9 	9D***1$78888 + )<(A(A(C(C 	2 	2$K++K88 2#[11112 trL   c           
         i }|s|S |                      |          }|st                              d           |S |\  }}t                              d|            	 |                     |          }t	          || j                  s0t                              d| dt          |           d           |S t          |j	                  }t          |d          rY|j        rQ|j                                        D ]6\  }}	|	r-t          |	d          r|	j        r	 d	}
|	j        }t	          || j                  rL|j        }t	          |t                     r0|                    d
          r|                    d          d         }
|                     |          }|
r|
|d<   ||j        |<   # t*          $ r?}dt!          |          v r t                              d| d| d|            Y d	}~d	}~wt.          $ r.}t                              d| d| d|            Y d	}~.d	}~ww xY w8||t!          |          <   n# t*          $ rR}dt!          |          v r t1          |dd          }t                              d| d| d| d           Y d	}~nPd	}~wt.          $ r@}t1          |dd          }t                              d| d| d| d           Y d	}~nd	}~ww xY w|S )zcExtract and resolve response information. Only includes the primary success response for MCP tools.z;No success responses found, tool will have no output schemaz Using primary success response: z2Expected Response after resolving for status code z, got z. Returning empty responses.)r   r   r   N#/components/schemas/rW   x-fastmcp-top-level-schemarx   r   z' in response : r\   r   z+Failed to extract response for status code z from reference 'rZ   Fry   )r   r+   r,   ri   r[   rF   rS   r|   r   r   rg   r   r   r   rB   r\   r]   r(   r_   r   r   r8   r6   r}   re   )rJ   r   extracted_responsesprimary_responser   r   response	resp_infor   r   top_level_schema_namer   rn   r   r=   r   s                   r?   _extract_responsesz OpenAPIParser._extract_responses  s    8:" 	'&&  ==>QRR 	'LLVWWW&&#3 [EEEFFFH	((55Hh(9:: +H H H>>H H H   +* %1EFFFI x++ '0@ '6>6F6L6L6N6N & &2NN&%#N4GHH% +<%
 481+9+KL),8JKK S*6*:#-gs#;#; !S@R@R$;A" A" !S =DMM#<N<Nr<R$9*.*F*F|*T*TK4 "$9 !,,H I HSI4^DD) 	 	 	NRU !S S     !&"LL!BN !B !B/:!B !B>?!B !B         )   "LL!BN !B !B/:!B !B>?!B !B        5>K 0 011 		 		 		>#a&&HH{E9==HLL4k 4 4#+4 4014 4         
  	 	 	{E9==HLL4k 4 4#+4 4014 4         	 #"sj   AI	 7A)I	 !BF21I	 2
H1<5G61I	 6H1#H,&I	 ,H11I	 	
K-AJ  K--6K((K-r   all_schemas	collectedc                 P    t                      fd |           S )al  
        Extract all schema names referenced by a schema (including transitive dependencies).

        Args:
            schema: The schema to analyze
            all_schemas: All available schema definitions
            collected: Set of already collected schema names (for recursion)

        Returns:
            Set of schema names that are referenced
        Nc                    t          | t                    rd| v rt          | d         t                    rk| d         }|                    d          r|                    d          d         }ndS .|vr*|v r&                    |            |                    |                                 D ]} |           dS t          | t                    r| D ]} |           dS dS )z%Recursively find all $ref references.z$ref)z#/$defs/r   rW   r   N)r[   rh   r]   r(   r_   addr   ra   )objr\   schema_namer   rU   r   r   	find_refss        r?   r   z=OpenAPIParser._extract_schema_dependencies.<locals>.find_refs'  s(   #t$$ $S==ZFS%A%A=f+C~~&KLL &)iinnR&8 "-'y88';66!k222!	+k":;;; !ZZ\\ % %EIe$$$$% %C&& $ $ $DIdOOOO$ $$ $rL   )set)rJ   r   r   r   r   s     ``@r?   _extract_schema_dependenciesz*OpenAPIParser._extract_schema_dependencies  sQ    " I	$ 	$ 	$ 	$ 	$ 	$ 	$8 		&rL   
parametersr   c                 T   t                      }|D ]9}|j        r0|                     |j                  }|                    |           :|rN|j        rG|j                                        D ]-}|                     |          }|                    |           .fd|D             S )aZ  
        Extract only the schema definitions needed for input (parameters and request body).

        Args:
            parameters: Route parameters
            request_body: Route request body
            all_schemas: All available schema definitions

        Returns:
            Dictionary containing only the schemas needed for input
        c                 *    i | ]}|v ||         S  r   .0r   r   s     r?   
<dictcomp>zDOpenAPIParser._extract_input_schema_dependencies.<locals>.<dictcomp>f  1     
 
 
(,$+BUBUD+d#BUBUBUrL   )r   schema_r   updater   r   )rJ   r   r   r   needed_schemasparamdepsr   s      `    r?   "_extract_input_schema_dependenciesz0OpenAPIParser._extract_input_schema_dependenciesF  s    "    	, 	,E} ,88TT%%d+++  	,L7 	,"."="D"D"F"F , ,88UU%%d++++
 
 
 
0>
 
 
 	
rL   	responsesc                    |rsi S t                      }|                                D ]}|j        s
|j                                        D ]}|                     |          }|                    |           |                    d          }t          |t                    r7|v r3|                    |           |                     |         |           fd|D             S )a  
        Extract only the schema definitions needed for outputs (responses).

        Args:
            responses: Route responses
            all_schemas: All available schema definitions

        Returns:
            Dictionary containing only the schemas needed for outputs
        r   )r   c                 *    i | ]}|v ||         S r   r   r   s     r?   r   zEOpenAPIParser._extract_output_schema_dependencies.<locals>.<dictcomp>  r   rL   )	r   r   r   r   r   r'   r[   r]   r   )rJ   r   r   r   r   r   r   r   s     `     r?   #_extract_output_schema_dependenciesz1OpenAPIParser._extract_output_schema_dependenciesj  s2     	 	I#&55!((** 	 	H* "*"9"@"@"B"B  88UU%%d+++,001MNNk3// K;4N4N"&&{33355#K0#"0 6   
 
 
 
0>
 
 
 	
rL   c                 	   g }t          | j        d          r| j        j        st                              d           g S i }t          | j        d          r| j        j        r| j        j        }t          |d          r|j        r|j                                        D ]\  }}	 t          || j	                  r.| 
                    |          }|                     |          ||<   n|                     |          ||<   b# t          $ r*}t                              d| d|            Y d}~d}~ww xY w|rA|                                D ],\  }}t          |t                    rt          |          ||<   -| j        j                                        D ]\  }}	t          |	| j                  s/t                              d| d	t!          |	           d
           Jt          |	d          r|	j        nd}
g d}|D ]}t%          |	|d          }|rt          || j                  r|                                }	 |                     t%          |dd          |
          }|                     t%          |dd                    }|                     t%          |dd                    }i }t          |d          r*|j        r#d |j                                        D             }|                     |||          }|                     ||          }t7          ||t%          |dd          t%          |dd          t%          |dd          t%          |dg           pg ||||||| j                  }	 t;          |d          \  }}||_        ||_        nK# t          $ r>}t                              d| d| d|            di d|_        i |_        Y d}~nd}~ww xY w|                     |           # tB          $ rV}dtE          |          v r t%          |dd          }t          #                    d| d| d | d!| d"#           Y d}~Xd}~wt          $ rD}t%          |dd          }t          #                    d| d| d | d!| d"#           Y d}~d}~ww xY wt          $                    d$tK          |           d%           |S )&z*Parse the OpenAPI schema into HTTP routes.pathsz$OpenAPI schema has no paths defined.rX   schemasz%Failed to extract schema definition 'rZ   Nz%Skipping invalid path item for path 'z	' (type: )r   )r'   putpostdeleteoptionsheadpatchtracerequestBodyr   rf   c                 D    i | ]\  }}|                     d           ||S )zx-)r(   )r   kvs      r?   r   z'OpenAPIParser.parse.<locals>.<dictcomp>  s@     * * *$(Aq#$<<#5#5* !1* * *rL   operationIdsummaryr   tags)rO   methodoperation_idr   r   r   r   r   r   request_schemasresponse_schemas
extensionsr9   F)convert_refsz)Failed to pre-calculate schema for route  r   object)r|   
propertiesrx   r   zFailed to process operation z (ID: z): Try   zFinished parsing. Extracted z HTTP routes.)&rg   r%   r   r+   rS   rX   r   r   r[   rB   ri   r   r}   rh   r   rH   r|   r   re   rG   upperr   r   r   rf   r   r   r   r9   r   flat_param_schemaparameter_mapr   r8   r]   r6   r,   len)rJ   routesschema_definitionsrX   r   r   r~   r=   path_strpath_item_objpath_level_paramshttp_methodsmethod_lower	operationmethod_upperr   r   r   r  input_schemasoutput_schemasrouteflat_schema	param_mapschema_errorop_errorop_ids                              r?   r5   zOpenAPIParser.parse  s   "$t|W-- 	T\5G 	NNABBBI  4<.. 	4<3J 	0Jz9-- *2D $.$6$<$<$>$>  LD&%fd.@AA .2.?.?.G.GO7;7S7S /8 8.t44 8<7S7S &8 8.t4 %   PDPPQPP         	N 2 8 8 : : N Nffd++ N/Ef/M/M&t, (,|'9'?'?'A'A s	 s	#HmmT-?@@ eHeetTaObObeee    =,77(( 	 	 	L !- [ [#M<FF	 XIt7I!J!J X#/#5#5#7#7LT%)%=%=#I|TBBDU& &
 -1,F,F#I}dCC- -) %)$;$;#I{DAA% %	 &(
"9m<< AV * *,5,A,G,G,I,I* * *J )-(O(O&-.) )
 *.)Q)Q%.* * !*!)#/)0M4)P)P$+Iy$$G$G(/	=$(O(O!(FB!?!?!E2'1):&/,9-;'1,0,@! ! !"55T %-26 6 62K 7BE32;E//( 	5 	5 	5"NN uL u u[c u ugs u u  
 )1.07 7E3 35E//////	5 e,,,,% 
 
 
Jc$O O   " '	=) L Ln<nn(nnZ_nndlnn%) %         %    '	=) L Ln<nn(nnZ_nndlnn%) %        m[z 	NCKKNNNOOOsi   %AD
D5 D00D5D5O?:"NO?
O%'4O O? O%%O??
R+	AQR+'9R&&R+)NN)N)'__name__
__module____qualname____doc__r   r|   r   r   r   r   r   r    r!   r]   rK   r   rT   r   ri   r   r   ra   r   r   r   r   boolr   rh   tupler   r   r   r   r   r   r   r   r5   r   rL   r?   r-   r-   m   sZ        fe// J'/ M	/
 J'/ |,/ 9o/ J'/ I/ / / / /.s ?P    5 5 5 5 5 5n# *    D .2-1a  a s)d*a  s)d*a  
m		a  a  a  a F@ @SWAW @ @ @ @D=3 =4 = = = =#'S>	sCx4	   .\##'S>D#8\#	c<	 \# \# \# \#D &*	1 11 #s(^1 s8d?	1
 
S1 1 1 1f"
'"
 &,"
 #s(^	"

 
c3h"
 "
 "
 "
H'
\)*'
 #s(^'
 
c3h	'
 '
 '
 '
R[tI [ [ [ [ [ [rL   r-   r@   N)6r  typingr   r   r   openapi_pydanticr   r   r   r	   r
   r   r   r   openapi_pydantic.v3.v3_0r)   r3   r0   r4   r.   r1   r2   r/   pydanticr   r   fastmcp.utilities.loggingr   modelsr   r   r   r   r   r   r   r   r   r  r+   r   r   r   r   r   r   r    r!   rh   r]   ra   r@   r-   __all__r   rL   r?   <module>r)     s
   N N ( ( ( ( ( ( ( ( ( (	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 ; : : : : : > > > > > > > > > > > > < < < < < < > > > > > > B B B B B B < < < < < < 8 8 8 8 8 8 / / / / / / / / 0 0 0 0 0 0                      
 
H		 7:w
33
')VY
/
/W\9l;;
W\9l;;
w~{NCCGK;77	W\9l;;
GK;77	3LtCH~ 3L$y/ 3L 3L 3L 3LlA A A A A		A A AL "rL   