
    k7i=                        S SK r S SKJrJrJrJrJr  S SKJrJ	r	J
r
JrJrJrJrJr  S SKJr  S SKJ	r  S SKJ
r  S SKJr  S SKJr  S S	KJr  S S
KJr  S SKJr  S SKJrJrJr  S SKJr  S SKJ r   \" \!5      r"\S   r#\S   r$\%\&\4   r' SDS\(S\&S\)S\&\(-  4S jjr*S\%S\&S\%\&\&4   4S jr+ " S S\ 5      r, " S S\ 5      r- " S S\ 5      r. " S S\ 5      r// S Qr0\" S!\\5      r1\" S"\\5      r2\" S#\\5      r3\" S$\
\5      r4\" S%\\5      r5\" S&\\5      r6\" S'\	\5      r7\" S(\\5      r8S)\%\&\4   S\(\/   4S* jr9 " S+ S,\\1\3\2\4\5\6\7\84   5      r:S-\'S-  S\'S-  4S. jr;S-\'S-  S\4S/ jr<SES0\S1\=S\&4S2 jjr>  SFS3\&S4\%\&\4   S5\(\,   S-  S6\-S-  S\&4
S7 jjr? SGS8\%\&\4   S9\&S-  S\%\&\4   4S: jjr@S-\%\&\4   S\%\&\4   4S; jrAS-\%\&\4   SS4S< jrBS-\%\&\4   \-  S\%\&\4   \-  4S= jrCS>\/S\%\&\4   4S? jrDS-\%\&\4   \(\   -  S\%\&\4   \(\   -  4S@ jrE  SFS4\%\&\.4   SA\%\&\4   S-  SB\&S-  S\%\&\4   S-  4SC jjrFg)H    N)AnyGenericLiteralTypeVarcast)OpenAPI	Operation	ParameterPathItem	ReferenceRequestBodyResponseSchema)r   )r	   )r
   )r   )r   )r   )r   )r   )	BaseModelFieldValidationError)
get_logger)FastMCPBaseModel)GETPOSTPUTDELETEPATCHOPTIONSHEADTRACEpathqueryheadercookievaluesparameter_nameis_query_parameterreturnc           	         [        S U  5       5      (       a  SR                  S U  5       5      $  / nU  H  n[        U[        5      (       aS  / nUR	                  5        H  u  pgUR                  U SU 35        M     UR                  SR                  U5      5        Mk  UR                  [        U5      5        M     SR                  U5      $ ! [         at  nU(       a  SOSn	[        R                  SU	 S	U S
U 35        U(       a  U s SnA$ [        R                  SSS5      n
[        U 5      R                  U
5      nUs SnA$ SnAff = f)aJ  
Format an array parameter according to OpenAPI specifications.

Args:
    values: List of values to format
    parameter_name: Name of the parameter (for error messages)
    is_query_parameter: If True, can return list for explode=True behavior

Returns:
    String (comma-separated) or list (for query params with explode=True)
c              3   l   #    U  H*  n[        U[        [        -  [        -  [        -  5      v   M,     g 7fN)
isinstancestrintfloatbool.0items     S/home/james-whalen/.local/lib/python3.13/site-packages/fastmcp/utilities/openapi.py	<genexpr>)format_array_parameter.<locals>.<genexpr>8   s(     
I&$:dC#I-455&s   24,c              3   8   #    U  H  n[        U5      v   M     g 7fr(   )r*   )r/   vs     r1   r2   r3   9   s     /1As   :.r   r   zFailed to format complex array z parameter '': N z[]'")alljoinr)   dictitemsappendr*   	Exceptionloggerwarning	maketrans	translate)r"   r#   r$   formatted_partsr0   
item_partskr6   e
param_typetranslation_table	str_values               r1   format_array_parameterrL   )   s-    
I&
IIIxx////D$%%
 JJLDA%%1QCj1 )&&sxx
';<&&s4y1  xx((  2W
-j\nEUUXYZX[\	
 M !$b"g >F--.?@Is*   BC 
E1E
E2EEEparam_valuec                     [        U [        5      (       d&  [        R                  SU S[	        U 5       35        0 $ 0 nU R                  5        H  u  p4U SU S3n[        U5      X%'   M     U$ )a  
Format a dictionary parameter for deepObject style serialization.

According to OpenAPI 3.0 spec, deepObject style with explode=true serializes
object properties as separate query parameters with bracket notation.

For example: `{"id": "123", "type": "user"}` becomes `param[id]=123&param[type]=user`.

Args:
    param_value: Dictionary value to format
    parameter_name: Name of the parameter

Returns:
    Dictionary with bracketed parameter names as keys
zdeepObject style parameter 'z' expected dict, got [])r)   r=   rA   rB   typer>   r*   )rM   r#   resultkeyvaluebracketed_keys         r1   format_deep_object_parameterrV   [   s~    $ k4((*>*::OPTU`PaObc	
 	F!'')
)*!C52 #E
 *
 M    c                       \ rS rSr% Sr\\S'   \\S'   Sr\	\S'   \
" SSS	9r\\S
'   Sr\S-  \S'   Sr\	S-  \S'   Sr\S-  \S'   Srg)ParameterInfo|   z>Represents a single parameter for an HTTP operation in our IR.namelocationFrequired.schema)aliasschema_Ndescriptionexplodestyle )__name__
__module____qualname____firstlineno____doc__r*   __annotations__ParameterLocationr]   r-   r   r`   
JsonSchemara   rb   rc   __static_attributes__rd   rW   r1   rY   rY   |   sU    H
IHd84GZ4"Kt"GTD[E3:rW   rY   c                   \    \ rS rSr% SrSr\\S'   \" \	S9r
\	\\4   \S'   Sr\S-  \S'   S	rg)
RequestBodyInfo   z<Represents the request body for an HTTP operation in our IR.Fr]   default_factorycontent_schemaNra   rd   )re   rf   rg   rh   ri   r]   r-   rj   r   r=   rs   r*   rl   ra   rm   rd   rW   r1   ro   ro      s<    FHd,1-NDj)  #Kt"rW   ro   c                   N    \ rS rSr% SrSr\S-  \S'   \" \	S9r
\	\\4   \S'   Srg)ResponseInfo   z*Represents response information in our IR.Nra   rq   rs   rd   )re   rf   rg   rh   ri   ra   r*   rj   r   r=   rs   rl   rm   rd   rW   r1   ru   ru      s+    4"Kt",1$,GNDj)GrW   ru   c                   *   \ rS rSr% Sr\\S'   \\S'   Sr\S-  \S'   Sr	\S-  \S'   Sr
\S-  \S'   \" \S	9r\\   \S
'   \" \S	9r\\   \S'   Sr\S-  \S'   \" \S	9r\\\4   \S'   \" \S	9r\\\4   \S'   \" \S	9r\\\4   \S'   Sr\S-  \S'   Srg)	HTTPRoute   z;Intermediate Representation for a single OpenAPI operation.r   methodNoperation_idsummaryra   rq   tags
parametersrequest_body	responsesschema_definitions
extensionsopenapi_versionrd   )re   rf   rg   rh   ri   r*   rj   
HttpMethodr{   r|   ra   r   listr}   r~   rY   r   ro   r=   r   ru   r   rl   r   r   r   rm   rd   rW   r1   rx   rx      s    E
I#L#*#GS4Z"Kt"D1D$s)1&+D&AJ]#A+/L/D(/).*ItC%&  161S*_-  "'t!<JS#X<"&OS4Z&rW   rx   )rx   r   rl   rY   rk   ro   ru   _handle_nullable_fields$extract_output_schema_from_responsesrV   parse_openapi_to_http_routesTOpenAPITSchema
TReference
TParameterTRequestBody	TResponse
TOperation	TPathItemopenapi_dictc                    U R                  SS5      n UR                  S5      (       aw  [        R                  " U 5      n[        R                  SUR                   35        [        U[        [        [        [        [        [        [        U5	      nUR                  5       $ [         R                  " U 5      n[        R                  SUR                   35        [        U["        [$        [&        [(        [*        [,        [.        U5	      nUR                  5       $ ! [0         aT  n[        R3                  SU 35        UR5                  5       n[        R3                  SU 35        [7        SU 35      UeS	nAff = f)
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.
openapir:   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_validaterA   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   r   
openapi_30parser
openapi_31rH   error_detailss          r1   r   r      sM    #&&y"5O)L%%e,,#22<@JLLB:CUCUBVW #
F <<>! !//=JLLB:CUCUBVW #
F <<>! L9!=>
*=/:;3M?CD!K	Ls    BD !A6D 
E6"AE11E6c                   :   \ rS rSrSrS\S\\   S\\   S\\	   S\\
   S\\   S	\\   S
\\   S\4S jrS\S\4S jrS\S\4S jrS\S\4S jr  SS\\   S-  S\\   S-  S\\   4S jjrS\S\S-  4S jrS\\\4   S-  S\\\4   4S jrS\\   4S jrSr g)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_clsr   c
                 p    Xl         X l        X0l        X@l        XPl        X`l        Xpl        Xl        Xl        g)z?Initialize the parser with the OpenAPI schema and type classes.N)	r   r   r   r   r   r   r   r   r   )
selfr   r   r   r   r   r   r   r   r   s
             r1   __init__OpenAPIParser.__init__  s8     *$* 0(**.rW   param_inr%   c                 F    US;   a  U$ [         R                  SU S35        g)z@Convert string parameter location to our ParameterLocation type.r   zUnknown parameter location: z, defaulting to 'query'r   )rA   rB   )r   r   s     r1   _convert_to_parameter_location,OpenAPIParser._convert_to_parameter_location$  s*    <<O5hZ?VWXrW   r0   c                 D   [        XR                  5      (       Ga  UR                  n UR                  S5      (       d  [	        SU 35      eUR                  S5      R                  S5      nU R                  nU GH:  nUR                  5       (       a$  [        U[        5      (       a  U[        U5         nO[        U[        5      (       a  XTR                  R                  ;   a  [        XES5      nOUR                  (       a  XTR                  ;   a  UR                  U   nO}US:X  a  [!        US5      (       a  UR"                  nOY[!        XE5      (       a  [        XES5      nO<SnO9[        U[$        5      (       a  UR'                  U5      nO[	        SU SU S35      eUb  GM+  [	        S	U S
U S35      e   [        X@R                  5      (       a  U R)                  U5      $ U$ U$ ! [*        [,        [.        [0        [        4 a  n[	        SU SU 35      UeSnAff = f)z.Resolves a reference to its target definition.#//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 'r9   )r)   r   refr   r   stripsplitr   isdigitr   r+   r   	__class__model_fieldsgetattrmodel_extrahasattrr   r=   r   _resolve_refAttributeErrorKeyError
IndexError	TypeError)r   r0   ref_strpartstargetpartrH   s          r1   r   OpenAPIParser._resolve_ref+  s   d..//hhG,Y))$//$I'S   d+11#6!D||~~*VT*B*B!'D	!2#FI66#3#3#@#@@%,V4%@F#//D<N<N4N%+%7%7%=F  $|38U8U)/):):!(!6!6)0t)D)-#FD11!'D!1(4TF:J7)STU  ~(.tf4I'RST 3 "< f&8&899,,V44  #Hj)ZP Y #@	QC!PQWXXYs$   E8G) &>G) %G) )HHH
schema_objc                     U R                  U5      n[        X R                  5      (       a  UR                  SSSS9nO<[        U[        5      (       a  UnO$[
        R                  S[        U5       S35        0 n[        U5      $ ! [         a3  nS[        U5      ;   a  e [
        R                  SU 3SS	9  0 s S
nA$ S
nAf[         a#  n[
        R                  SU 3SS	9  0 s S
nA$ S
nAff = f)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)r   r)   r   
model_dumpr=   rA   rB   rQ   _replace_ref_with_defsr   r*   r   r@   )r   r   resolved_schemarR   rH   s        r1   _extract_schema_as_dict%OpenAPIParser._extract_schema_as_dict_  s    	"//
;O/OO==(33$T 4  OT22(;D<Q;RRij )&11 	>#a&HLL=aSAELRI 	LL=aSAELRI	s0   BB 
C.(B>8C.>C.C)#C.)C.Noperation_paramspath_item_paramsc                    / n0 nU=(       d    / U=(       d    / -   nU GHs  n U R                  U5      n[        XpR                  5      (       d$  [        R	                  S[        U5       S35        MT  UR                  nSSKJn	  [        X5      (       a  UR                  OUn
U R                  U
5      nUR                  nUR                  U
4nX;   a  M  SXM'   0 nU(       aj  U R                  U5      nU R                  U5      n[        XR                  5      (       d-  [        US5      (       a  UR                   b  UR                   US'   O[        US5      (       a  UR"                  (       a  [%        ['        UR"                  R)                  5       5      S5      nU(       a  [        US	5      (       a  UR*                  (       av  UR*                  nU R                  U5      nU R                  U5      n[        UU R                  5      (       d-  [        US5      (       a  UR                   b  UR                   US'   [-        US
S5      n[-        USS5      n[/        UR                  UUR0                  UUR2                  UUS9nUR5                  U5        GMv     U$ ! [6         a>  n[-        US[-        USS5      5      n[        R9                  SU SU 3SS9   SnAGM  SnAff = f)z<Extract and resolve parameters from operation and path item.z(Expected Parameter after resolving, got . Skipping.r   )EnumTdefaultNcontentmedia_type_schemarb   rc   )r[   r\   r]   r^   ra   rb   rc   r[   r   unknownzFailed to extract parameter 'r9   Fr   )r   r)   r   rA   rB   rQ   r   enumr   rT   r   param_schemar[   r   r   r   r   r   nextiterr"   r   r   rY   r]   ra   r?   r@   r   )r   r   r   extracted_paramsseen_params
all_paramsparam_or_ref	parameterr   r   param_in_strparam_locationparam_schema_obj	param_keyparam_schema_dictr   first_media_typemedia_schemaresolved_media_schemarb   rc   
param_inforH   
param_names                           r1   _extract_parameters!OpenAPIParser._extract_parameters|  s    13  	 ',"1A1GRH
&LR --l;	!)-?-?@@NNB4	?BSS^_  %--% '1&@&@HNNh  "&!D!D\!R#,#9#9  '^^\:	+)-& %'!#(,(D(DEU(V% '+&7&78H&IO&8J8JKK#OY??+33?7F7N7N))4Y	22y7H7H'+D1B1B1I1I1K,Ld'S$(#$46IJJ,>>'7'I'I,0,H,H,V) 150A0A,0O- *+@$BTBT U U '(=y I I 5 = = I;P;X;X-i8 ")Y=	7D9 +"+&//, ) 5 5#
 !''
3Y 'j    $ &',y*Q
 3J<s1#FQV   	s&   AJ2A JF=J
K "2KK request_body_or_refc                    U(       d  g U R                  U5      n[        X R                  5      (       d#  [        R	                  S[        U5       S35        g[        UR                  UR                  S9n[        US5      (       a  UR                  (       a}  UR                  R                  5        H_  u  pEU(       d  M  [        US5      (       d  M!  UR                  (       d  M4   U R                  UR                  5      nUUR                  U'   Ma     U$ ! [         a6  nS[!        U5      ;   a  e [        R#                  SU S	U 35         SnAM  SnAf[$         a&  n[        R#                  SU S	U 35         SnAM  SnAff = f! [         aA  nS[!        U5      ;   a  e ['        US
S5      n[        R#                  SU S	U 3SS9   SnAgSnAf[$         a1  n['        US
S5      n[        R#                  SU S	U 3SS9   SnAgSnAff = f)z-Extract and resolve request body information.Nz*Expected RequestBody after resolving, got z. Returning None.)r]   ra   r   r   r   )Failed to extract schema for media type 'r9   r   r   z Failed to extract request body 'Fr   )r   r)   r   rA   rB   rQ   ro   r]   ra   r   r   r>   r   r   rs   r   r*   r   r@   r   )	r   r   r   request_body_infomedia_type_strmedia_type_objschema_dictrH   ref_names	            r1   _extract_request_body#OpenAPIParser._extract_request_body  s   ";	,,-@ALl,A,ABB@lAS@TTef  !0%..(44! |Y//L4H4H6B6J6J6P6P6R2N&#N4GHH*<<<*.*F*F . @ @+K !, .<<^L 7S6 %$  * NRU !S   !&"LL"KNK[[^_`^a b   ) "LL"KNK[[^_`^a b   	>#a&H2E9EHLL28*CsCe    	2E9EHLL28*CsCe   	ss   AF A$F  F F '*DF 
F!+EF FF :F  FF 
H7GH'HHoperation_responsesc                    0 nU(       d  U$ UR                  5        GH  u  p4 U R                  U5      n[        XPR                  5      (       d'  [        R                  SU S[        U5       S35        MY  [        UR                  S9n[        US5      (       a  UR                  (       a|  UR                  R                  5        H^  u  pxU(       d  M  [        US5      (       d  M!  UR                  (       d  M4   U R                  UR                  5      n	XR                  U'   M`     Xb[        U5      '   GM     U$ ! [         a9  n
S[        U
5      ;   a  e [        R!                  SU S	U S
U
 35         Sn
A
M  Sn
A
f["         a)  n
[        R!                  SU S	U S
U
 35         Sn
A
M  Sn
A
ff = f! [         aF  n
S[        U
5      ;   a  e [%        USS5      n[        R!                  SU SU SU
 3SS9   Sn
A
GM  Sn
A
f["         a6  n
[%        USS5      n[        R!                  SU SU SU
 3SS9   Sn
A
GM  Sn
A
ff = f)z)Extract and resolve response information.z2Expected Response after resolving for status code z, got r   )ra   r   r   r   r  z' in response : Nr   r   z+Failed to extract response for status code z from reference 'r9   Fr   )r>   r   r)   r   rA   rB   rQ   ru   ra   r   r   r   r   rs   r   r*   r   r@   r   )r   r
  extracted_responsesstatus_coderesp_or_refresponse	resp_infor  r  r  rH   r  s               r1   _extract_responses OpenAPIParser._extract_responses!  sx    8:"&&(;(A(A(C$K<,,[9!(,=,=>>NNL[M Z#H~.k;  )X5I5IJ	 8Y//H4D4D:B:J:J:P:P:R6*N '8K L L . @ @ @".2.J.J$2$D$D/" LW 8 8 H ;S8 9BC$45Y )D~ #"I $. 
" %T'*1v%. %* &&OP^O_ `33>-r!%F!" !" $- " &&OP^O_ `33>-r!%F!" !""  	Bc!fL";yAA+ O''/jA38"   
  ";yAA+ O''/jA38"   ss   AF15AF1F1%F19)D:"F1:
F..E82F18F.F)#F1)F..F11
H?;:G<<H?	*H::H?c                    / n[        U R                  S5      (       a  U R                  R                  (       d  [        R	                  S5        / $ 0 n[        U R                  S5      (       a  U R                  R
                  (       a  U R                  R
                  n[        US5      (       a  UR                  (       aw  UR                  R                  5        HY  u  pE [        XPR                  5      (       a&  U R                  U5      nU R                  U5      X$'   MF  U R                  U5      X$'   M[     U R                  R                  R                  5        GH  u  p[        XR                  5      (       d'  [        R	                  SU S	[        U	5       S
35        MG  [        U	S5      (       a  U	R                  OSn
/ SQnU GH  n[!        XS5      nU(       d  M  [        XR"                  5      (       d  M5  UR%                  5       n U R'                  [!        USS5      U
5      nU R)                  [!        USS5      5      nU R+                  [!        USS5      5      n0 n[        US5      (       aY  UR,                  (       aH  UR,                  R                  5        VVs0 s H!  u  nnUR/                  S5      (       d  M  UU_M#     nnn[1        UU[!        USS5      [!        USS5      [!        USS5      [!        US/ 5      =(       d    / UUUUUU R2                  S9nUR5                  U5        [        R7                  SU SU 35        GM     GM     [        R7                  S[?        U5       S 35        U$ ! [         a'  n[        R	                  SU SU 35         SnAGM  SnAff = fs  snnf ! [8         aI  nS[;        U5      ;   a  e [!        USS5      n[        R=                  SU SU SU SU 3SS9   SnAGM<  SnAf[         a9  n[!        USS5      n[        R=                  SU SU SU SU 3SS9   SnAGM}  SnAff = f)!z*Parse the OpenAPI schema into HTTP routes.pathsz$OpenAPI schema has no paths defined.r   schemasz%Failed to extract schema definition 'r9   Nz%Skipping invalid path item for path 'z	' (type: )r~   )r   putpostdeleteoptionsheadpatchtracerequestBodyr   r   zx-operationIdr|   ra   r}   )r   rz   r{   r|   ra   r}   r~   r   r   r   r   r   zSuccessfully extracted route:  r   r   zFailed to process operation z (ID: z): Tr   zFinished parsing. Extracted z HTTP routes.) r   r   r  rA   rB   r   r  r>   r)   r   r   r   r@   r   rQ   r~   r   r   upperr   r  r  r   r   rx   r   r?   r   r   r*   r   len)r   routesr   r   r[   r^   r   rH   path_strpath_item_objpath_level_paramshttp_methodsmethod_lower	operationmethod_upperr~   r  r   r   rG   r6   routeop_errorop_ids                           r1   r   OpenAPIParser.parsek  s#   "$t||W--T\\5G5GNNABI  4<<..4<<3J3J00Jz9--*2D2D$.$6$6$<$<$>LD%f.@.@AA.2.?.?.GO7;7S7S /8.4 8<7S7S &8.4 %?" (,||'9'9'?'?'A#Hm-?-?@@;H:YtTaObNccde  =,77 (( 	L !-#MF	9I7I7I!J!J#/#5#5#7L7%)%=%=#I|TBDU&
 -1,F,F#I}dC-) %)$;$;#I{DA%	 &(
"9m<<AVAV -6,A,A,G,G,I*,IDAq#$<<#5 !%1,I ' * !*!)#/)0M4)P$+Iy$$G(/	=$(O!(FB!?!E2'1):&//A'1,0,@,@! e,<\N!H:VW !-1 (Bp 	3CK=NO % CD6QCP h*0 & 
Jc$O  " '	=) L:<.(SYZ_Y``cdlcmn%) %   %  '	=) L:<.(SYZ_Y``cdlcmn%) %  s\    >M; M;BN5#N/
N/
BN5;
N,N''N,/N55
Q	?=PQ	-QQ	)	r   r   r   r   r   r   r   r   r   NN)!re   rf   rg   rh   ri   r   rQ   r   r   r   r   r   r   r   r*   r   rk   r   r   r   rl   r   r   rY   r   ro   r  r=   ru   r  rx   r   rm   rd   rW   r1   r   r      sd    f// J'/ M	/
 J'/ |,/ 9o/ J'/ I/ /.s ?P 2 2 2h# * > .2-1a s)d*a  s)d*a  
m		a F@ @SWAW @DH##'S>D#8H#	c<	 H#TwtI wrW   r   r^   c                 :   U (       a  [        U [        5      (       d  U $ U R                  5       n/ SQnU H  nX1;   d  M
  UR                  U5        M     SU;   aP  US   R	                  5        VVs0 s H  u  pEU[        U5      _M     snnUS'   US   (       d  UR                  S5        SU;   a,  [        US   5      US'   US   (       d  UR                  S5        SU;   a4  [        US   [        5      (       a  [        US   5      US'   gUS   SL a  gggs  snnf )zO
Clean up a schema dictionary for display by removing internal/complex fields.
)allOfanyOfoneOfnotnullablediscriminatorreadOnly	writeOnly
deprecatedxmlexternalDocs
propertiesr>   additionalPropertiesTN)r)   r=   copypopr>   clean_schema_for_display)r^   cleanedfields_to_removefieldrG   r6   s         r1   rA  rA    s+    FD11 kkmG& "KK "
 w7>|7L7R7R7T!
7TtqA'**7T!
 |$KK%'3GG4DEwKK (g45t<<.F.//G*+ +,4 5 )!
s   0Dc                    U (       a  [        U [        5      (       d  gSU ;   a  U S   $ SU ;   a*  [        U S   [        5      (       a  U S   (       a  U S   S   $ SU ;   a*  [        U S   [        5      (       a  U S   (       a  U S   S   $ SU ;   a  U S   $ U R                  S5      nUS:X  a  0 nU R                  S	0 5      n[        U[        5      (       a|  [	        U R                  S
/ 5      5      n[        UR                  5       5      SS nU H  nXc;   d  M
  [        X6   5      X&'   M     U H   nXr;  d  M
  Xs;   d  M  [        X7   5      X''   M"     U(       a  U$ SS0$ US:X  a<  U R                  S5      n[        U[        5      (       a  [        U5      n	U	b  U	/$ / $ S/$ US:X  a5  U R                  S5      n
U
S:X  a  gU
S:X  a  gU
S:X  a  gU
S:X  a  gU
S:X  a  ggUS:X  a  gUS :X  a  g!US":X  a  g#US$:X  a  gg%)&zm
Generate a simple example value from a JSON schema dictionary.
Very basic implementation focusing on types.
r   r   r   r   examplesexamplerQ   objectr=  r]   N   rS   rT   arrayr>   example_itemstringformatz	date-timez2024-01-01T12:00:00Zdatez
2024-01-01emailzuser@example.comuuidz$123e4567-e89b-12d3-a456-426614174000bytezZXhhbXBsZQ==integer   numberg      ?booleanTnullunknown_type)r)   r=   r   r   setkeysgenerate_example_from_schema)r^   schema_typerR   r=  required_propsprops_to_include	prop_namereq_propitems_schemaitem_exampleformat_types              r1   rZ  rZ  !  s4   
 FD11 Fi  Jvf~t<<f~a   	fvj)400:j!!$$Fi  **V$KhZZb1
j$'' J!;<N#JOO$56  .	*(D"-)F% . +)h.D'C",(F$ +
  v5eW%55		zz'*lD))7EL%1%=L>E2E		 jj*+%)& '!%& 9& !			!		 			!		 rW   dataindentc                 d     [         R                  " XS9nSU S3$ ! [         a	    SU  S3s $ f = f)z8Formats Python data as a JSON string block for markdown.rd  z```json
z
```z!```
Could not serialize to JSON: )r   dumpsr   )rc  rd  json_strs      r1   format_json_for_descriptionri  t  sE    @::d28*E** @3D6??@s    //base_descriptionr   r~   r   c           
      
  ^ U /nU(       Ga(  U Vs/ s H  oUR                   S:X  d  M  UPM     nnU(       aj  SnUR                  U5        U HQ  nUR                  (       a  SOSn	SUR                   SU	 SUR                  =(       d    S 3n
UR                  U
5        MS     U Vs/ s H  oUR                   S	:X  d  M  UPM     nnU(       aj  S
nUR                  U5        U HQ  nUR                  (       a  SOSn	SUR                   SU	 SUR                  =(       d    S 3n
UR                  U
5        MS     U(       Gac  UR                  (       GaQ  SnUR                  U5        UR                  (       a  SOSn	UR                  SUR                   U	 35        UR
                  (       a  SUR
                  ;   a  SO[        [        UR
                  5      S5      nU(       a  UR
                  R                  U0 5      n[        U[        5      (       a  SU;   a  UR                  S5        US   R                  5        Ha  u  nn[        U[        5      (       d  M  SU;   d  M%  XR                  S/ 5      ;   nU(       a  SOSnUR                  SU SU SUS    35        Mc     T(       Ga  SnSn1 Skn[        U4S jU 5       S5      nTR                  5       n[        U5       GHI  u  nnU(       d  UR                  U5        SnUU:X  a  SOSnUR                  SU SU SUR                  =(       d    S 35        UR
                  (       d  Mk  SUR
                  ;   a  SO[        [        UR
                  5      S5      nU(       d  M  UR
                  R                  U5      nUR                  SU S35        [        U[        5      (       Ga  UR                  S5      S:X  a  SU;   a  US   n[        U[        5      (       am  SU;   ag  UR                  S5        US   R                  5        H?  u  nn[        U[        5      (       d  M  SU;   d  M%  UR                  SU S US    35        MA     OmSU;   ag  UR                  S!5        US   R                  5        H?  u  nn[        U[        5      (       d  M  SU;   d  M%  UR                  SU S US    35        MA     U(       d  GM  [        U5      nUS":w  d  GM  Uc  GM  UR                  S#5        UR                  [        US$S%95        GML     SR                  U5      $ s  snf s  snf )&a$  
Formats the base description string with response, parameter, and request body information.

Args:
    base_description (str): The initial description to be formatted.
    responses (dict[str, Any]): A dictionary of response information, keyed by status code.
    parameters (list[ParameterInfo] | None, optional): A list of parameter information,
        including path and query parameters. Each parameter includes details such as name,
        location, whether it is required, and a description.
    request_body (RequestBodyInfo | None, optional): Information about the request body,
        including its description, whether it is required, and its content schema.

Returns:
    str: The formatted description string with additional details about responses, parameters,
    and the request body.
r   z

**Path Parameters:**z (Required)r:   z
- **z**r  zNo description.r   z

**Query Parameters:**z

**Request Body:**
application/jsonNr=  z

**Request Properties:**ra   r]   z

**Responses:**F>   200201202204c              3   6   >#    U  H  oT;   d  M
  Uv   M     g 7fr(   rd   )r/   sr   s     r1   r2   4format_description_with_responses.<locals>.<genexpr>  s     J-Q	>qq-s   		Tz
 (Success)z  - Content-Type: ``rQ   rJ  r>   z"
  - **Response Item Properties:**z	
    - **z**: z
  - **Response Properties:**rW  z
  - **Example:**   rf  )r\   r?   r]   r[   ra   rs   r   r   r   r)   r=   r>   sortedrZ  ri  r<   )rj  r   r~   r   
desc_partsppath_paramsparam_sectionparamrequired_marker
param_descquery_paramsreq_body_section
media_typer^   r^  prop_schemar]   req_markresponse_sectionadded_response_sectionsuccess_codessuccess_statusresponses_to_processr  r  status_markerr`  rG  s    `                           r1   !format_description_with_responsesr  }  s   0 ##J ",E*Q

f0Dq*E6Mm,$38>>-r%ejj\O3DBuGXGXGm\mFno
!!*- % $.G:aw1F:G7Mm,%38>>-r%ejj\O3DBuGXGXGm\mFno
!!*- & 0002*++7+@+@-bB|7788IJK && &)D)DD #$|::;TB 
 %4488RHfd++0F%%&CD282F2L2L2N.	;&{D99 - <'0JJz24N'NH8@}bH&--"(2hZr+mB\A] ^ 3O /!& 5J-JDQ  )0&,-A&B"K)!!"23)-&,7>,ILrMRb9N9N9cRc8de
 ''' *Y-E-EE 'd9#;#;<dC  :&5599*EF%%(;J<q&IJ "&$//!::f-8W=N+1'?L *< > >$0L$@ * 1 12W X>J$0?""'%'?*$:I{ )3;(E(E,9[,H(2(9(9.84TaHbGc,d)*?* *V3&--.NO:@:N:T:T:V 6	;$.{D$A$A(5(D$.$5$5*4YKtKP]D^C_(`%& ;W v">v"F"n49L&--.BC&-- ;GA Ny 'C@ 99Z  y F Hs   U U %U<Uinfora   c                 &   U R                  5       nUR                  S5      =n(       an  [        U[        5      (       aX  UR	                  S5      (       a  UR                  S5      S   nSU 3US'   OUR	                  S5      (       d  [        SU S35      eOUR                  S	5      =n(       aH  SU;   a  [        U5      US	'   OYUR                  5        VVs0 s H  u  pgU[        U5      _M     snnUS	'   O&UR                  S
5      =n(       a  [        U5      US
'   S H7  n	[        UR                  U	/ 5      5       H  u  p[        U5      X)   U
'   M     M9     U R                  SU5      (       a  UR                  S5      (       d  XS'   U$ s  snnf )a  
Replace openapi $ref with jsonschema $defs

Examples:
- {"type": "object", "properties": {"$ref": "#/components/schemas/..."}}
- {"$ref": "#/components/schemas/..."}
- {"items": {"$ref": "#/components/schemas/..."}}
- {"anyOf": [{"$ref": "#/components/schemas/..."}]}
- {"allOf": [{"$ref": "#/components/schemas/..."}]}
- {"oneOf": [{"$ref": "#/components/schemas/..."}]}

Args:
    info: dict[str, Any]
    description: str | None

Returns:
    dict[str, Any]
$ref#/components/schemas/r   #/$defs/r   r   z. FastMCP only supports local schema references starting with '#/'. Please include all schema definitions within the OpenAPI document.r=  r>   )r3  r2  r4  ra   )
r?  r   r)   r*   r   r   r   r   r>   	enumerate)r  ra   r^   ref_pathschema_namer=  r^  r  item_schemasectionir0   s               r1   r   r     s   * YY[F::f%%x%h$$""#:;;&nnS1"5#+K=!9v((.. EhZ PY Z 
 zz,/	/	/Z#9*#EF<  /9.>.>.@$.@*I 1+>>.@$F<  

7+	+	+0=w. GR!89GA!7!=FOA : / xx{++FJJ}4M4M +}M$s   Fc                    SU ;   d  SU ;   d  SU ;   a  U $ [        U R                  S5      [        5      (       a  SU S   ;   a  U $ SU ;   az  U S   n[        U[        5      (       a`  SU0n0 n[	        5       nUS:X  a  1 SknO
US:X  a  1 S	knU R                  5        H  u  pVUS:X  a  M  XT;   a  XbU'   M  XcU'   M     USS0/US'   U$ U $ )
z
Make an optional parameter schema nullable to allow None values.

For optional parameters, we need to allow null values in addition to the
specified type to handle cases where None is passed for optional parameters.
r3  r4  r2  rQ   rV  rJ  >	   r>   containsmaxItemsminItemsmaxContainsminContainsprefixItemsuniqueItemsunevaluatedItemsrH  >   r]   r=  maxPropertiesminPropertiespropertyNamespatternPropertiesr>  unevaluatedProperties)r)   r   r   r*   rX  r>   )r^   original_typenested_non_nullable_schemanullable_schematype_specific_propertiesrS   rT   s          r1   !_make_optional_parameter_nullabler  L  s     &Gv-F1B &**V$d++&.0H vmS)) *& !O (+u$'
,( (*	,( %lln
&=46;s3+0C( - )CVVDT'UOG$""MrW   c                    SU ;   aI  U S   n[        U[        5      (       a  US/U S'   g[        U[        5      (       a  SU;  a
  / UQSPU S'   gggSU ;   a  / U R                  S5      QSS0PU S'   gSU ;   a2  [	        S U S    5       5      (       d  U S   R                  SS05        ggSU ;   a  SU R                  S5      0SS0/U S'   gg)zdAdd 'null' to the schema's type field or handle oneOf/anyOf/allOf constructs if not already present.rQ   rV  r4  r3  c              3   H   #    U  H  oR                  S 5      S:H  v   M     g7f)rQ   rV  N)r   r.   s     r1   r2   $_add_null_to_type.<locals>.<genexpr>  s     J/$88F#v-/s    "r2  N)r)   r*   r   r@  anyr?   )r^   current_types     r1   _add_null_to_typer    s    f~lC((*F3F6Nd++\)!8<!8!8v * , 
F	BFJJw/B&&1ABw	F	J&/JJJ7O""FF#34 K	F	#VZZ%89FF;KLw 
rW   c                    [        U [        5      (       d  U $ SU ;   nU=(       a5    U S   =(       a)    SU ;   =(       d    SU ;   =(       d    SU ;   =(       d    SU ;   nSnSU ;   a;  U S   R                  5        H$  n[        U[        5      (       d  M  SU;   d  M"  Sn  O   U(       d	  U(       d  U $ U R                  5       nU(       a#  UR	                  S5        U(       a  [        U5        U(       a  SU;   az  US   R                  5        Hc  u  pd[        U[        5      (       d  M  SU;   d  M$  UR	                  S5      nU(       d  M>  SU;   d  SU;   d  SU;   d  SU;   d  MX  [        U5        Me     U$ )	z{Convert OpenAPI nullable fields to JSON Schema format: {"type": "string",
"nullable": true} -> {"type": ["string", "null"]}r6  rQ   r4  r3  r2  Fr=  T)r)   r=   r"   r?  r@  r  r>   )r^   has_root_nullable_fieldhas_root_nullable_truehas_property_nullable_fieldr  rR   
_prop_namenullable_values           r1   r   r     si    fd## )F2 	
:	
 f !& !& ! &   #(v!,/668K+t,,{1J.2+ 9 #+F [[]F 

:!f% #|v'='-l';'A'A'C#J+t,,{1J!,!<!>k)+-+-+-%k2 (D MrW   r,  c                 @  ^^ 0 n/ n[        5       [        5       [        5       [        5       S.n0 nU R                   H*  nX5R                     R                  UR                  5        M,     U R
                  (       a  U R
                  R                  (       a  [        [        U R
                  R                  5      5      n[        U R
                  R                  U   R                  5       U R
                  R                  5      nUR                  S0 5      n[        5       nUR                  5        H  n	UR                  U	5        M     [        UR                  5       5      n
X-  nU R                   GH3  nUR                  U;   a  UR                   SUR                   3nUR                   (       a  UR#                  U5        [        UR$                  R                  5       UR                  5      nUR                  SS5      nSUR                  R'                  5        S3nU(       a  U SU 3US'   OXS'   XU'   M  UR                   (       a  UR#                  UR                  5        [        UR$                  R                  5       UR                  5      nXUR                  '   GM6     U R
                  (       av  U R
                  R                  (       a[  UR)                  5        H  u  nnUUU'   M     U R
                  R                   (       a!  UR+                  WR                  S	/ 5      5        S
UUS.nU R,                  (       a  U R,                  R                  5       US'   UR                  S5      SL a  UR/                  S5        SU;   a  [        5       mUU4S jmUR)                  5        H  u  nnUS:w  d  M  T" U5        M     T(       a7  US   R)                  5        VVs0 s H  u  nnUT;   d  M  UU_M     snnUS'   U$ UR/                  S5        U$ s  snnf )z
Combines parameter and request body schemas into a single schema.
Handles parameter name collisions by adding location suffixes.

Args:
    route: HTTPRoute object

Returns:
    Combined schema dictionary
r   r=  __ra   r:   (z parameter)r!  r]   rH  )rQ   r=  r]   $defsr>  Fc                 v  > [        U [        5      (       a|  SU ;   aV  [        U S   [        5      (       a>  U S   nUR                  S5      (       a#  TR	                  UR                  S5      S   5        U R                  5        H  nT" U5        M     g [        U [        5      (       a  U  H  nT" U5        M     g g Nr  r  r   r  r)   r=   r*   r   addr   r"   r   rT   r   r6   r0   find_refs_in_value	used_refss       r1   r  ,_combine_schemas.<locals>.find_refs_in_valueI      %&&U?z%-'E'E-C~~j11!ciinR&89A&q) (E4((!D&t, " )rW   )rX  r~   r\   r  r[   r   rs   r   r   r   r?  ra   r   r"   updaterY  r]   r?   r`   
capitalizer>   extendr   r@  )r,  r=  r]   param_names_by_location
body_propsr|  content_typebody_schemaall_non_body_paramslocation_paramsbody_param_namescolliding_paramssuffixed_namer   original_desclocation_descr^  r  rR   rS   rT   r[   
def_schemar  r  s                          @@r1   _combine_schemasr    s    JH %%	 J!!/33EJJ? " e00??D!3!3!B!BCD,--l;@@B**
 !__\26
 %299;""?3 < :??,-*= !!::))$zzl"U^^,<=M~~. 2""$e&7&7L ),,]B?M 9 9 ;<KHM1>q.P]+.;]+
 )5}% ~~

+1""$e&7&7L &2uzz"C "H e00??&0&6&6&8"I{$/Jy! '9 &&OOKOOJ;<  F 22779w zz()U2

)* &E	
	- !,,.JCg~"5) )
  )/w(=(=(?(?$D*9$ !j (?F7O M JJwMs   &P7Pc                 (   [        U [        5      (       a  SU ;   nSnU R                  5        H#  n[        U[        [        -  5      (       d  M!  Sn  O   U(       d	  U(       d  U $ U R	                  5       nU(       a  UR                  S5      US'   U(       aD  UR                  5        H0  u  pS[        U[        [        -  5      (       d  M#  [        U5      XE'   M2     U$ [        U [        5      (       a  U  Vs/ s H  n[        U5      PM     sn$ U $ s  snf )zPRecursively replace 'oneOf' with 'anyOf' in schema to handle overlapping unions.r4  FTr3  )r)   r=   r"   r   r?  r@  r>   _adjust_union_types)r^   
has_one_ofneeds_recursive_processingr6   rR   rG   r0   s          r1   r  r  g  s     &$&
%*" A!TD[))-1* ! "<M $jj1F7O &a-- 3A 6FI ' 	FD	!	!6<=fd#D)f==M >s   5Dr   r   c                    ^^ U (       d  g/ SQnSnU H  nXP;   d  M
  X   n  O   Uc3  U R                  5        H  u  pVUR                  S5      (       d  M  Un  O   Ub  UR                  (       d  g/ SQnSnU H#  n	XR                  ;   d  M  UR                  U	   n  O   UcV  UR                  (       aE  [        [	        UR                  5      5      n
UR                  U
   n[
        R                  SU
 35        U(       a  [        U[        5      (       d  gUR                  5       nSU;   aM  U(       aF  US   nUR                  S5      (       a+  UR                  S5      S	   nX;   a  X   R                  5       nU(       a!  UR                  S
5      (       a  [        U5      nUR                  S5      S:w  a  SSU0S/SS.nUnU(       af  SUR                  5       ;  aR  0 nUR                  5        H8  u  nnU(       a&  UR                  S
5      (       a  [        U5      UU'   M3  UUU'   M:     XS'   UR                  S5      SL a  UR                  S5        SU;   a  [        5       mUU4S jmUR                  5        H  u  nnUS:w  d  M  T" U5        M     T(       a6  US   R                  5        VVs0 s H  u  nnUT;   d  M  UU_M     snnUS'   OUR                  S5        [        [        [         ["        4   [%        U5      5      nU$ s  snnf )a  
Extract output schema from OpenAPI responses for use as MCP tool output schema.

This function finds the first successful response (200, 201, 202, 204) with a
JSON-compatible content type and extracts its schema. If the schema is not an
object type, it wraps it to comply with MCP requirements.

Args:
    responses: Dictionary of ResponseInfo objects keyed by status code
    schema_definitions: Optional schema definitions to include in the output schema
    openapi_version: OpenAPI version string, used to optimize nullable field handling

Returns:
    dict: MCP-compliant output schema with potential wrapping, or None if no suitable schema found
N)rn  ro  rp  rq  2)rm  zapplication/vnd.api+jsonzapplication/hal+jsonzapplication/ld+jsonz	text/jsonz/Using non-JSON content type for output schema: r  r  r   r  r   rQ   rH  rR   T)rQ   r=  r]   zx-fastmcp-wrap-resultr  r>  Fc                 v  > [        U [        5      (       a|  SU ;   aV  [        U S   [        5      (       a>  U S   nUR                  S5      (       a#  TR	                  UR                  S5      S   5        U R                  5        H  nT" U5        M     g [        U [        5      (       a  U  H  nT" U5        M     g g r  r  r  s       r1   r  @extract_output_schema_from_responses.<locals>.find_refs_in_value  r  rW   )r>   r   rs   r   r   rA   r   r)   r=   r?  r   r   r   r@  rX  r   r*   r   r  )r   r   r   r  response_infor  r  json_compatible_typesr^   r  first_content_typeoutput_schemar  r  wrapped_schemaprocessed_defsdef_namer  rS   rT   r[   r  r  s                        @@r1   r   r     s   (  1M M$#%2M % &/oo&7"K%%c** ) '8
 M$@$@ F-777"11,?F . ~-66!$}'C'C"DE--.@A=>P=QR	
 FD11 KKMM #5 (677"..-b1K0 2 ? D D F
 ?55e<</>  H, #]3!
%)	
 ' fFKKM9$6$<$<$> Hj?#=#=e#D#D+B:+Nx(+5x( %? "0g /0E901 -E	
	- (--/JCg~"5) 0
  )6g(>(D(D(F&(F$D*9$ !j (F&M'" g& c3h)<])KLM&s   1L
L
)F)rv  r0  r(   )Gr   typingr   r   r   r   r   openapi_pydanticr   r	   r
   r   r   r   r   r   openapi_pydantic.v3.v3_0r   r   r   r   r   r   r   r   pydanticr   r   r   fastmcp.utilities.loggingr   fastmcp.utilities.typesr   re   rA   r   rk   r=   r*   rl   r   r-   rL   rV   rY   ro   ru   rx   __all__r   r   r   r   r   r   r   r   r   r   rA  rZ  r+   ri  r  r   r  r  r   r  r  r   rd   rW   r1   <module>r     s    7 7	 	 	 ; > > < > B < 8 6 6 0 4	H	
 G
 ?@ #s(^
 CH//"%/;?/4Z/d'*	#s(^B	$ 	#& #H# H'  ', :w
3
)VY
/\9l;
\9l;
~{NCK;7	\9l;
K;7	3LtCH~ 3L$y/ 3Llc		cL9Z$%6 9:;L 9xPd): Ps Pf@c @3 @s @ .2+/Y!Y!SY!
 ]#d*Y! "D(Y! 	Y!z 590
sCx.0'*Tz0	#s(^0fCd38n Cc3h CLMd38n M M05DcNS$8 5T#s(^c=Q 5pBI B$sCx. BJ!cNT#Y&!	#s(^d3i!L 15"&UC%&US#X-U 4ZU 
#s(^d	UrW   