
    lKj	                        d Z ddlmZ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      Z0de1e2ef   de3e   fdZ4 G d dee)e+e*e,e-e.e/e0f         Z5ddgZ6y) zHOpenAPI parsing logic for converting OpenAPI specs to HTTPRoute objects.    )AnyGenericTypeVarcast)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                    | j                  dd      }	 |j                  d      rvt        j                  |       }t        j                  d|j                          t        |t        t        t        t        t        t        t        |	      }|j                         S t!        j                  |       }t        j                  d|j                          t        |t"        t$        t&        t(        t*        t,        t.        |	      }|j                         S # t0        $ rT}t        j3                  d|        |j5                         }t        j3                  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          q/Users/ahmed/devFolder/Ultron/claude-voice/.venv/lib/python3.12/site-packages/fastmcp/utilities/openapi/parser.pyparse_openapi_to_http_routesrA   7   sJ    #&&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 A5D 	E.AE))E.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&y)*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
                     || _         || _        || _        || _        || _        || _        || _        || _        |	| _        y)z?Initialize the parser with the OpenAPI schema and type classes.N)	r&   rC   rD   rE   rF   rG   rH   rI   r:   )
selfr&   rC   rD   rE   rF   rG   rH   rI   r:   s
             r@   __init__zOpenAPIParser.__init__{   sJ     *$* 0(**.    param_inr$   c                 |    |dv rt        t        |      S t        j                  d| d       t        t        d      S )z@Convert string parameter location to our ParameterLocation type.)pathqueryheadercookiezUnknown parameter location: z, defaulting to 'query'rQ   )r   r   r,   warning)rK   rN   s     r@   _convert_to_parameter_locationz,OpenAPIParser._convert_to_parameter_location   s>    <<)8445hZ?VWX%w//rM   itemc                     t        || j                        r|j                  }t        |t              s|S 	 |j	                  d      st        d|       |j                  d      j                  d      }| j                  }|D ]  }|j                         rt        |t              r|t        |         }nt        |t              r||j                  j                  v rt        ||d      }n|j                   r||j                   v r|j                   |   }no|dk(  rt#        |d      r|j$                  }nQt#        ||      rt        ||d      }n7d}n4t        |t&              r|j)                  |      }nt        d| d| d      |t        d	| d
| d       t        || j                        r| j+                  |      S |S |S # t,        t.        t0        t2        t
        f$ r}t        d| d|       |d}~ww xY w)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 '': )
isinstancerC   refstrr)   r9   stripsplitr&   isdigitlistintr   	__class__model_fieldsgetattrmodel_extrahasattrrY   dictr(   _resolve_refAttributeErrorKeyError
IndexError	TypeError)rK   rV   ref_strpartstargetpartr>   s          r@   rj   zOpenAPIParser._resolve_ref   s   dD../hhGgs+,Y))$/$I'S   d+11#6!D||~*VT*B!'D	!2#FI66#3#3#@#@@%,VT4%@F#//DF<N<N4N%+%7%7%=F  $|38U)/):):!(!6)0t)D)-#FD1!'D!1(4TF:J7)STU  ~(.tf4I'RST 3 "< fd&8&89,,V44  #Hj)ZP Y #@	QC!PQWXXYs$   EG 
9G G G=&G88G=
schema_objc                    	 | j                  |      }t        || j                        r|j                  ddd      }n7t        |t              r|}n$t
        j                  dt        |       d       i }t        |      }|S # t        $ r4}dt        |      v r t
        j                  d| d	       i cY d
}~S d
}~wt        $ r&}t
        j                  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)rj   r\   rD   
model_dumpri   r,   rT   typer   r9   r^   r7   	Exception)rK   rs   resolved_schemaresultr>   s        r@   _extract_schema_as_dictz%OpenAPIParser._extract_schema_as_dict   s    	"//
;O/4??;(33$T 4  OT2(;D<Q;RRij  ,F3FM 	>#a&HLL=aSAELRI 	LL=aSAELRI	s0   A?B 	C,)B:4C,:C,C'!C,'C,Noperation_paramspath_item_paramsc                 <   g }i }|xs g |xs g z   }|D ]8  }	 | j                  |      }t        || j                        s#t        j	                  dt        |       d       O|j                  }ddlm}	 t        ||	      r|j                  n|}
| j                  |
      }|j                  }|j                  |
f}||v rd||<   i }|r`| j                  |      }| j                  |      }t        || j                        st        |d      r|j                   |j                   |d<   nt        |d      r|j"                  rt%        t'        |j"                  j)                               d      }|rt        |d	      rw|j*                  rk|j*                  }| j                  |      }| j                  |      }t        || j                        s't        |d      r|j                   |j                   |d<   t-        |d
d      }t-        |dd      }t/        |j                  ||j0                  ||j2                  ||      }|j5                  |       ; |S # t6        $ r@}t-        |dt-        |dd            }t        j9                  d| d| d       Y d}~d}~ww xY w)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 'r[   Frz   )rj   r\   rE   r,   rT   r}   rN   enumr   valuerU   param_schemar   r   rC   rh   r   r   nextitervaluesr   rf   r   r   r   appendr~   r7   )rK   r   r   extracted_paramsseen_params
all_paramsparam_or_ref	parameterrN   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
&LR --l;	!)T-?-?@NNB4	?BSS^_  %--% '14&@HNNh  "&!D!D\!R#,#9#9  '^^\:	+)-I& %'!#(,(D(DEU(V% '+&7&78H&IO&8J8JK#OY?+33?7F7N7N))4Y	2y7H7H'+D1B1B1I1I1K,Ld'S$(#$46IJ,>>'7'I'I,0,H,H,V) 150A0A,0O- *+@$BTBT U '(=y I 5 = = I;P;X;X-i8 ")Y=	7D9 +"+&//, ) 5 5#
 !''
3Y 'j    $ &',y*Q
 3J<s1#FQV   	s&   A	I#AI?FI	J5JJrequest_body_or_refc                    |sy	 | j                  |      }t        || j                        s#t        j	                  dt        |       d       yt        |j                  |j                        }t        |d      rv|j                  rj|j                  j                         D ]M  \  }}|s	t        |d      s|j                  s#	 | j                  |j                        }||j                  |<   O |S # t        $ r3}dt!        |      v r t        j#                  d| d	|        Y d}~d}~wt$        $ r%}t        j#                  d| d	|        Y d}~d}~ww xY w# t        $ rB}dt!        |      v r t'        |d
d      }t        j#                  d| d	| d       Y d}~yd}~wt$        $ r4}t'        |d
d      }t        j#                  d| d	| d       Y d}~y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   ry   )Failed to extract schema for media type 'r[   r]   r   z Failed to extract request body 'Frz   )rj   r\   rF   r,   rT   r}   r   r   r   rh   r   itemsr   r   content_schemar9   r^   r7   r~   rf   )	rK   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   ";	,,-@ALlD,A,AB@lAS@TTef  !0%..(44! |Y/L4H4H6B6J6J6P6P6R2NN&#N4G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	E AE +E 8E *C40E 4	E=)D+&E +E7EE EE 	G%(8F%%G%1*G  G%status_codec                     	 t        |      }d|cxk  xr dk  S c S # t        t        f$ r |j                         dv cY S w xY w)z>Check if a status code represents a successful response (2xx).   i,  )r   2xx)rc   r9   rn   lower)rK   r   code_ints      r@   _is_success_status_codez%OpenAPIParser._is_success_status_code  sP    	=;'H((S((((I& 	=$$&*<<<	=s     !A Aoperation_responsesc                     |syg d}|D ]  }||v s|||   fc S  |j                         D ]  \  }}| j                  |      s||fc S  y)zTGet the primary success response for an MCP tool. We only need one success response.N)200201202204207)r   r   )rK   r   priority_codescoder   resp_or_refs         r@   _get_primary_success_responsez+OpenAPIParser._get_primary_success_response  sp     # = #D**1$788 #
 )<(A(A(C$K++K8#[11 )D
 rM   c           
         i }|s|S | j                  |      }|st        j                  d       |S |\  }}t        j                  d|        	 | j                  |      }t	        || j
                        s't        j                  d| dt        |       d       |S t        |j                        }t        |d      r|j                  r|j                  j                         D ]  \  }}	|	rt        |	d      r|	j                  r	 d	}
|	j                  }t	        || j                        rA|j                  }t	        |t               r%|j#                  d
      r|j%                  d      d   }
| j'                  |      }|
r|
|d<   ||j(                  |<   |j(                  j1                  |i         ||t!        |      <   |S # t*        $ r7}dt!        |      v r t        j-                  d| d| d|        Y d	}~d	}~wt.        $ r)}t        j-                  d| d| d|        Y d	}~Gd	}~ww xY w# t*        $ rF}dt!        |      v r t3        |dd      }t        j-                  d| d| d| d       Y d	}~|S d	}~wt.        $ r8}t3        |dd      }t        j-                  d| d| d| d       Y d	}~|S d	}~ww xY w)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/rX   x-fastmcp-top-level-schemary   r   z' in response : r]   r   z+Failed to extract response for status code z from reference 'r[   Frz   )r   r,   r-   rj   r\   rG   rT   r}   r   r   rh   r   r   r   rC   r]   r^   r)   r`   r   r   r9   r7   r~   
setdefaultrf   )rK   r   extracted_responsesprimary_responser   r   response	resp_infor   r   top_level_schema_namer   ro   r   r>   r   s                   r@   _extract_responsesz OpenAPIParser._extract_responses  s7    8:"&&  ==>QRLLVW&&#3 [7}EFL	((5Hh(9(9:H V>**FH +* %1E1EFI x+0@0@6>6F6F6L6L6N2NN&#N4GH*<< 481+9+K+KL),8J8JK*6*:*:#-gs#;@R@R$;A" =DMM#<Nr<R$9*.*F*F|*TK4$9 !,,H I HSI44^D& "00;;NBOU 7OX 5>K 01& #"O  * 	NRU !S   !&"LL"KNK[ \//:m2aS!B   ) "LL"KNK[ \//:m2aS!B   		>#a&H{E9=HLL=k] K##+*Cs4    #"  	{E9=HLL=k] K##+*Cs4    #"	si   AH4 A(H4 BG-H4 	H1
,G<6H4 <H1H,&H4 ,H11H4 4	K=;I>>K
-J==Kr   all_schemas	collectedc                 B    
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
        c                 t   t        | t              rd| v ret        | d   t              rR| d   }|j                  d      r|j	                  d      d   }ny$|vr |v rj                  |        |          | j                         D ]
  } |        yt        | t              r| D ]
  } |        yy)z%Recursively find all $ref references.z$ref)z#/$defs/r   rX   r   N)r\   ri   r^   r)   r`   addr   rb   )objr]   schema_namer   rV   r   r   	find_refss        r@   r   z=OpenAPIParser._extract_schema_dependencies.<locals>.find_refs+  s    #t$S=ZFS%Af+C~~&KL&)iinR&8 "-'y8';6!k2!+k":; !ZZ\Ee$ *C&DdO   'rM   )set)rK   r   r   r   r   s     ``@r@   _extract_schema_dependenciesz*OpenAPIParser._extract_schema_dependencies  s'    " I	$8 	&rM   
parametersr   c                 t   t               }|D ]<  }|j                  s| j                  |j                  |      }|j                  |       > |rN|j                  rB|j                  j                         D ]%  }| j                  ||      }|j                  |       ' |D ci c]  }||v s|||    c}S c c}w )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
        )r   schema_r   updater   r   )	rK   r   r   r   needed_schemasparamdepsr   r   s	            r@   "_extract_input_schema_dependenciesz0OpenAPIParser._extract_input_schema_dependenciesJ  s    "   E}}88T%%d+   L77"."="="D"D"F88U%%d+ #G 1?
0>$+BUD+d##
 	
 
s    	B5*B5	responsesc                    |r|si S t               }|j                         D ]  }|j                  s|j                  j                         D ]t  }| j                  ||      }|j	                  |       |j                  d      }t        |t              sH||v sM|j                  |       | j                  ||   ||       v  |D ci c]  }||v s|||    c}S c c}w )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   )	r   r   r   r   r   r(   r\   r^   r   )	rK   r   r   r   r   r   r   r   r   s	            r@   #_extract_output_schema_dependenciesz1OpenAPIParser._extract_output_schema_dependenciesn  s     I#&5!((*H**"*"9"9"@"@"B88U%%d+,001MNk3/K;4N"&&{355#K0#"0 6  #C	 +$ 1?
0>$+BUD+d##
 	
 
s   	CCc                 F	   g }t        | j                  d      r| j                  j                  st        j	                  d       g S i }t        | j                  d      r| j                  j
                  r| j                  j
                  }t        |d      r|j                  rs|j                  j                         D ]V  \  }}	 t        || j                        r&| j                  |      }| j                  |      ||<   n| j                  |      ||<   X |r7|j                         D ]$  \  }}t        |t              st        |      ||<   & | j                  j                  j                         D ]  \  }}	t        |	| j                        s&t        j	                  d| d	t!        |	       d
       Ct        |	d      r|	j"                  nd}
g d}|D ]  }t%        |	|d      }|st        || j&                        s+|j)                         }	 | j+                  t%        |dd      |
      }| j-                  t%        |dd            }| j/                  t%        |dd            }i }t        |d      rJ|j0                  r>|j0                  j                         D ci c]  \  }}|j3                  d      r|| }}}| j5                  |||      }| j7                  ||      }t9        ||t%        |dd      t%        |dd      t%        |dd      t%        |dg       xs g ||||||| j:                        }	 t=        |d      \  }}||_        ||_         |jC                  |         t        jK                  d$tM        |       d%       |S # t        $ r&}t        j	                  d| d|        Y d}~d}~ww xY wc c}}w # t        $ r9}t        j	                  d| d| d|        di d|_        i |_         Y d}~d}~ww xY w# tD        $ rI}dtG        |      v r t%        |dd      }t        jI                  d| d| d | d!| d"#       Y d}~d}~wt        $ r;}t%        |dd      }t        jI                  d| d| d | d!| d"#       Y d}~d}~ww xY w)&z*Parse the OpenAPI schema into HTTP routes.pathsz$OpenAPI schema has no paths defined.rY   schemasz%Failed to extract schema definition 'r[   Nz%Skipping invalid path item for path 'z	' (type: )r   )r(   putpostdeleteoptionsheadpatchtracerequestBodyr   rg   zx-operationIdsummaryr   tags)rP   methodoperation_idr   r   r   r   r   r   request_schemasresponse_schemas
extensionsr:   F)convert_refsz)Failed to pre-calculate schema for route  r   object)r}   
propertiesry   r   zFailed to process operation z (ID: z): Trz   zFinished parsing. Extracted z HTTP routes.)'rh   r&   r   r,   rT   rY   r   r   r\   rC   rj   r   r~   ri   r   rI   r}   r   rf   rH   upperr   r   r   rg   r)   r   r   r   r:   r   flat_param_schemaparameter_mapr   r9   r^   r7   r-   len)rK   routesschema_definitionsrY   r   r   r   r>   path_strpath_item_objpath_level_paramshttp_methodsmethod_lower	operationmethod_upperr   r   r   r   kvinput_schemasoutput_schemasrouteflat_schema	param_mapschema_errorop_errorop_ids                                r@   r6   zOpenAPIParser.parse  s   "$t||W-T\\5G5GNNABI  4<<.4<<3J3J00Jz9-*2D2D$.$6$6$<$<$>LD&%fd.@.@A.2.?.?.GO7;7S7S /8.t4 8<7S7S &8.t4 %?"  2 8 8 :ffd+/Ef/M&t, !;
 (,||'9'9'?'?'A#HmmT-?-?@;H:YtTaObNccde  =,7 (( 	L !-#M<F	It7I7I!J#/#5#5#7LT%)%=%=#I|TBDU&
 -1,F,F#I}dC-) %)$;$;#I{DA%	 &(
"9m<AVAV -6,A,A,G,G,I*,IDAq#$<<#5 !"1,I ' * )-(O(O&-.)
 *.)Q)Q%.* !*!)#/)0M4)P$+Iy$$G(/	=$(O!(FB!?!E2'1):&/,9-;'1,0,@,@!"55T %-262K 7BE32;E/ e,U !-1 (Bj 	3CK=NOG % CD6QCP v*T  ) 	5"NN"KL>YZ[cZddfgsft u
 )1.07E3 35E//	5 & 
Jc$O  " '	=) L:<.(SYZ_Y``cdlcmn%) %   %  '	=) L:<.(SYZ_Y``cdlcmn%) %  s{   ANBPO
;A:P6OP	N>N99N>P	P	/P?PP		P	R >QR %0RR )NN)N)'__name__
__module____qualname____doc__r   r}   r   r   r   r   r    r!   r"   r^   rL   r   rU   r   rj   r   r   rb   r   r   r   r   boolr   ri   tupler   r   r   r   r   r   r   r   r6    rM   r@   r.   r.   m   si    f// J'/ M	/
 J'/ |,/ 9o/ J'/ I/ /.0s 0?P 05 5 5n# * D .2-1a s)d*a  s)d*a  
m		a F@ @SWAW @D=3 =4 =#'S>	sCx4	.`##'S>D#8`#	c<	 `#L &*	11 #s(^1 s8d?	1
 
S1f"
'"
 &,"
 #s(^	"

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