
    Ki"                        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Z5y) 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                    | 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          l/home/jay/workspace/scripts/.codegraph-venv/lib/python3.12/site-packages/fastmcp/utilities/openapi/parser.pyparse_openapi_to_http_routesr@   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_clsr9   c
                     || _         || _        || _        || _        || _        || _        || _        || _        |	| _        y)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__{   sJ     *$* 0(**.    param_inr#   c                 B    |dv r|S t         j                  d| d       y)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   s*    <<O5hZ?VWXrL   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 '': )
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../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)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   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 '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	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S	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   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   ";	,,-@ALlD,A,AB@lAS@TTef  !0%..(44! |Y/L4H4H6B6J6J6P6P6R 2NN&#N4GH*<<*.*F*F . @ @+K !, .<<^L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)rb   r8   rm   lower)rJ   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   )rJ   r   priority_codescoder   resp_or_refs         r?   _get_primary_success_responsez+OpenAPIParser._get_primary_success_response  sy     # = # 	9D**1$788	9
 )<(A(A(C 	2$K++K8#[11	2
 rL   c           
      T   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 ]  \  }}	|	s	t        |	d      s|	j                  s#	 d	}
|	j                  }t	        || j                        rA|j                  }t	        |t               r%|j#                  d
      r|j%                  d      d   }
| j'                  |      }|
r|
|d<   ||j(                  |<    ||t!        |      <   |S # t*        $ r6}dt!        |      v r t        j-                  d| d| d|        Y d	}~d	}~wt.        $ r)}t        j-                  d| d| d|        Y d	}~,d	}~ww xY w# t*        $ rF}dt!        |      v r t1        |dd      }t        j-                  d| d| d| d       Y d	}~|S d	}~wt.        $ r8}t1        |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/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LLVW&&#3 [7}EFH	((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/&P 5>K 01& #"G  * 	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    #"	su   AH AH .H ;H 	BF'H '	H0,G!H !H-HH HH 	J'";I##J'/-J""J'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   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f+C~~&KL&)iinR&8 "-'y8';6!k2!+k":; !ZZ\ %Ee$%C& $DdO$ 'rL   )set)rJ   r   r   r   r   s     ``@r?   _extract_schema_dependenciesz*OpenAPIParser._extract_schema_dependencies  s'    " I	$8 	&rL   
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   )	rJ   r   r   r   needed_schemasparamdepsr   r   s	            r?   "_extract_input_schema_dependenciesz0OpenAPIParser._extract_input_schema_dependenciesF  s    "    	,E}}88T%%d+	, L77"."="="D"D"F ,88U%%d+, 1?
(,$+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   )	rJ   r   r   r   r   r   r   r   r   s	            r?   #_extract_output_schema_dependenciesz1OpenAPIParser._extract_output_schema_dependenciesj  s     I#&5!((* 	H**"*"9"9"@"@"B 88U%%d+,001MNk3/K;4N"&&{355#K0#"0 6 		$ 1?
(,$+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.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   zx-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   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   kvinput_schemasoutput_schemasrouteflat_schema	param_mapschema_errorop_errorop_ids                                r?   r5   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 : Nffd+/Ef/M&t,N
 (,||'9'9'?'?'A s	#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*$(Aq#$<<#5 !"1*J * )-(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[1s	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]   rK   r   rT   r   ri   r   r   ra   r   r   r   r   boolr   rh   tupler   r   r   r   r   r   r   r   r5    rL   r?   r-   r-   m   si    f// J'/ M	/
 J'/ |,/ 9o/ J'/ I/ /.s ?P 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<	 \#D &*	11 #s(^1 s8d?	1
 
S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 ( (	 	 	 ; > > < > 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A		AL "rL   