
    kKj:?                    X   U d 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 ddl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 ddl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,m-Z-m.Z. ddl/m0Z0 ddl1m2Z2m3Z3 dgZ4 e*e5      Z6dZ7de8d<    G d de      Z9y)zHOpenAPIProvider for creating MCP components from OpenAPI specifications.    )annotations)Counter)AsyncIteratorSequence)asynccontextmanager)AnyLiteralcastN)
SchemaPath)Prompt)ResourceResourceTemplate)Provider)OpenAPIResourceOpenAPIResourceTemplateOpenAPITool_extract_mime_type_from_route_slugify)DEFAULT_ROUTE_MAPPINGSComponentFnMCPTypeRouteMap
RouteMapFn_determine_route_type)Tool)FastMCPComponent)
get_logger)	HTTPRoute$extract_output_schema_from_responsesparse_openapi_to_http_routes)RequestDirector)VersionSpecversion_sort_keyOpenAPIProviderg      >@floatDEFAULT_TIMEOUTc                  V    e Zd ZdZ	 dddddddd	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d fdZedd       Zedd       Z	 d	 	 	 	 	 ddZ		 	 	 	 	 	 dd	Z
	 	 	 	 	 	 	 	 dd
Z	 	 	 	 	 	 	 	 ddZ	 	 	 	 	 	 	 	 ddZddZ	 d	 	 	 	 	 ddZddZ	 d	 	 	 	 	 ddZd dZ	 d	 	 	 	 	 d!dZd"dZd#dZ xZS )$r$   ab  Provider that creates MCP components from an OpenAPI specification.

    Components are created eagerly during initialization by parsing the OpenAPI
    spec. Each component makes HTTP calls to the described API endpoints.

    Example:
        ```python
        from fastmcp import FastMCP
        from fastmcp.server.providers.openapi import OpenAPIProvider
        import httpx

        client = httpx.AsyncClient(base_url="https://api.example.com")
        provider = OpenAPIProvider(openapi_spec=spec, client=client)

        mcp = FastMCP("API Server")
        mcp.add_provider(provider)
        ```
    NT)
route_mapsroute_map_fnmcp_component_fn	mcp_namestagsvalidate_outputc                  t         |           |du | _        || j                  |      }|| _        || _        || _        t               t               t               t               d| _        i | _	        i | _
        i | _        	 t        j                  t        t        |            | _        t#        | j                         | _        t/        |      }
|xs g t0        z   }|
D ]g  }t3        ||      }|j4                  }|J	  |||      }|>|}t(        j7                  d|j8                   d|j:                   d|j<                          | jA                  ||      }tC        |jD                        |jF                  z  |xs
 tC               z  }|tH        jJ                  k(  r| jM                  |||       |tH        jN                  k(  r| jQ                  |||       |tH        jR                  k(  r| jU                  |||       $|tH        jV                  k(  s9t(        j7                  d|j8                   d|j:                          j t(        j7                  dtY        |
       d       y# t&        $ r)}	t(        j+                  d       t-        d|	       |	d}	~	ww xY w# t&        $ r>}	t(        j?                  d|j8                   d|j:                   d	|	 d
       Y d}	~	d}	~	ww xY w)ak  Initialize provider by parsing OpenAPI spec and creating components.

        Args:
            openapi_spec: OpenAPI schema as a dictionary
            client: Optional httpx AsyncClient for making HTTP requests.
                If not provided, a default client is created using the first
                server URL from the OpenAPI spec with a 30-second timeout.
                To customize timeout or other settings, pass your own client.
            route_maps: Optional list of RouteMap objects defining route mappings
            route_map_fn: Optional callable for advanced route type mapping
            mcp_component_fn: Optional callable for component customization
            mcp_names: Optional dictionary mapping operationId to component names
            tags: Optional set of tags to add to all components
            validate_output: If True (default), tools use the output schema
                extracted from the OpenAPI spec for response validation. If
                False, a permissive schema is used instead, allowing any
                response structure while still returning structured JSON.
        N)toolresourceresource_templatepromptz$Failed to initialize RequestDirectorzInvalid OpenAPI specification: zRoute  z mapping customized: type=zError in route_map_fn for : z. Using default values.)r,   zExcluding route: zCreated OpenAPIProvider with z routes)-super__init___owns_client_create_default_client_client_mcp_component_fn_validate_outputr   _used_names_tools
_resources
_templatesr   	from_dictr
   r   _specr!   	_director	Exceptionlogger	exception
ValueErrorr    r   r   mcp_typedebugmethodpathnamewarning_generate_default_namesetr,   mcp_tagsr   TOOL_create_openapi_toolRESOURCE_create_openapi_resourceRESOURCE_TEMPLATE_create_openapi_templateEXCLUDElen)selfopenapi_specclientr(   r)   r*   r+   r,   r-   ehttp_routesroute	route_map
route_typeresultcomponent_name
route_tags	__class__s                    z/Users/ahmed/devFolder/Ultron/claude-voice/.venv/lib/python3.12/site-packages/fastmcp/server/providers/openapi/provider.pyr6   zOpenAPIProvider.__init__G   s   < 	"dN>00>F!1 / I	!(i	5
 /168>@	K#--d3.EFDJ,TZZ8DN
 3<@ !&B*@@
 E-eZ@I"++J')%<F)%+
$U\\N!EJJ< @$$.OO#46 "88	JNUZZ9+=+==OJW\\)))%j)Qw///--e^*-Uw888--e^*-Uw.0a

|LM; !> 	4S5E4FgNOO  	KCD>qcBCJ	K* ! NN4U\\N!EJJ<rRSQT U0 1 s2   AI- >A	J"-	J6$JJ"	K)+3K$$K)c                T   |j                  dg       }|r|d   j                  d      st        d      |d   d   }|d   j                  di       }|j                         D ]+  \  }}|j                  d| d|j                  dd	            }- t	        j
                  |t        
      S )zACreate a default httpx client from the OpenAPI spec's server URL.serversr   urlzyNo server URL found in OpenAPI spec. Either add a 'servers' entry to the spec or provide an httpx.AsyncClient explicitly.	variables{}default )base_urltimeout)getrF   itemsreplacehttpxAsyncClientr&   )clsrY   rf   rm   rh   rK   vars          rd   r8   z&OpenAPIProvider._create_default_client   s     ""9b1gajnnU3P  1:e$AJNN;3	"*ID#''"TF"swwy"7MNH +  (OLL    c                  K   | j                   r+| j                  4 d{    d ddd      d{    yd y7  7 # 1 d{  7  sw Y   yxY ww)z6Manage the lifecycle of the auto-created httpx client.N)r7   r9   rX   s    rd   lifespanzOpenAPIProvider.lifespan   s:      ||| $||  $||||sA   AA AAAAAAA
AAAc                2   |xs i }|j                   r=|j                   |v r||j                      }nH|j                   j                  d      d   }n)|j                  xs |j                   d|j                   }t        |      }t        |      dkD  r|dd }|S )z'Generate a default name from the route.__r   _8   N)operation_idsplitsummaryrI   rJ   r   rW   )rX   r]   mcp_names_maprK   s       rd   rM   z&OpenAPIProvider._generate_default_name   s     &+!!]2$U%7%78))//5a8==Bu||nAejj\$BD~t9r>9Drv   c           	         | j                   |   |xx   dz  cc<   | j                   |   |   dk(  r|S | d| j                   |   |    }t        j                  d| d| d| d       |S )z9Ensure the name is unique by appending numbers if needed.   r|   zName collision: 'z' exists as z	. Using 'z'.)r<   rD   rH   )rX   rK   component_typenew_names       rd   _get_unique_namez OpenAPIProvider._get_unique_name   s     	(.!3.N+D1Q6KV1T--n=dCDEv\.1A8*TVW	
 rv   c                   |j                   }t        |j                  |j                  |j                        }| j
                  s|ddd}|j                  d      rd|d<   |}| j                  |d      }|j                  xs* |j                  xs d|j                   d|j                   }t        | j                  || j                  ||||t        |j                   xs g       |z  	      }	| j"                  ,	 | j#                  ||	       t$        j'                  d
| d       |	| j,                  |	j.                  <   y# t(        $ r%}
t$        j+                  d| d|
        Y d}
~
Cd}
~
ww xY w)z#Create and register an OpenAPITool.NobjectT)typeadditionalPropertieszx-fastmcp-wrap-resultr/   z	Executes r3   )rZ   r]   directorrK   description
parametersoutput_schemar,   zTool  customized by component_fnzError in component_fn for tool r4   )flat_param_schemar   	responsesresponse_schemasopenapi_versionr;   ro   r   r   r   rI   rJ   r   r9   rB   rN   r,   r:   rD   rH   rC   rL   r=   rK   )rX   r]   rK   r,   combined_schemar   
permissive	tool_namebase_descriptionr/   r[   s              rd   rQ   z$OpenAPIProvider._create_openapi_tool   sy     11<OO""!!
 $$)B !(,*J   !896:
23&M))$7	 7}}75<<.%**6 	 <<^^(&'UZZ%2&-	
 !!-S&&ud3uYK/JKL "&DII  S!@2aSQRRSs   ;+E   	E.	E))E.c                2   | j                  |d      }d| }|j                  xs |j                  xs d|j                   }t	        | j
                  || j                  |||t        |      t        |j                  xs g       |z        }| j                  ,	 | j                  ||       t        j                  d| d       || j                  t!        |j"                        <   y# t        $ r%}t        j                  d| d	|        Y d}~Ld}~ww xY w)
z'Create and register an OpenAPIResource.r0   resource://zRepresents )rZ   r]   r   urirK   r   	mime_typer,   Nz	Resource r   z#Error in component_fn for resource r4   )r   r   r   rJ   r   r9   rB   r   rN   r,   r:   rD   rH   rC   rL   r>   strr   )	rX   r]   rK   r,   resource_nameresource_urir   r0   r[   s	            rd   rS   z(OpenAPIProvider._create_openapi_resource  s    --dJ?$]O4LLK

|2L 	 #<<^^(3E:UZZ%2&-	
 !!-&&uh7y6QRS .6HLL)*  9,r!M s   +C( (	D1DDc                   | j                  |d      }t        d |j                  D              }d| }|r|ddj                  d |D              z   z  }|j                  xs |j
                  xs d|j                   }d|j                  D ci c]  }|j                  dk(  r|j                  i t        |j                  t              r|j                  j                         ni |j                  r6t        |j                  t              rd	|j                  v sd	|j                  ini  c}|j                  D cg c]+  }|j                  dk(  s|j                  s |j                  - c}d
}	t        | j                  || j                   ||||	t#        |j$                  xs g       |z  t'        |      	      }
| j(                  ,	 | j)                  ||
       t*        j-                  d| d       |
| j2                  |
j4                  <   yc c}w c c}w # t.        $ r%}t*        j1                  d| d|        Y d}~Md}~ww xY w)z/Create and register an OpenAPIResourceTemplate.r1   c              3  T   K   | ]   }|j                   d k(  s|j                   " yw)rJ   N)locationrK   .0ps     rd   	<genexpr>z;OpenAPIProvider._create_openapi_template.<locals>.<genexpr>E  s"     V-=vAUQVV-=s   ((r   /c              3  (   K   | ]
  }d | d  yw)ri   rj   N r   s     rd   r   z;OpenAPIProvider._create_openapi_template.<locals>.<genexpr>H  s     .O;aA3bz;s   zTemplate for r   rJ   r   )r   
propertiesrequired)	rZ   r]   r   uri_templaterK   r   r   r,   r   Nz	Template r   z#Error in component_fn for template r4   )r   sortedr   joinr   r   rJ   r   rK   
isinstanceschema_dictcopyr   r   r9   rB   rN   r,   r   r:   rD   rH   rC   rL   r?   r   )rX   r]   rK   r,   template_namepath_paramsuri_template_strr   r   template_params_schematemplater[   s               rd   rU   z(OpenAPIProvider._create_openapi_template<  s<    --d4GHVU-=-=VV(8chh.O;.O&O OO NNM%**2N 	
  )) *A::'  
+5aii+Fqyy~~'B
 ==&qyy$7MQYY<V '6
  
 
 *  !& 0 0 01AJJ&4HQZZ 0#"
, +<<^^)(-UZZ%2&-3E:

 !!-&&uh7y)9(::UVW 2:--.S*  9:J9K2aSQ s1   BH;HHH+H 	I I  Ic                P   K   t        | j                  j                               S w)z/Return all tools created from the OpenAPI spec.)listr=   valuesrx   s    rd   _list_toolszOpenAPIProvider._list_tools  s     DKK&&())   $&c                   K   | j                   j                  |      }|y||j                  |j                        sy|S w)zGet a tool by name.N)r=   ro   matchesversion)rX   rK   r   r/   s       rd   	_get_toolzOpenAPIProvider._get_tool  s?      {{t$<wt||'D   ?Ac                P   K   t        | j                  j                               S w)z3Return all resources created from the OpenAPI spec.)r   r>   r   rx   s    rd   _list_resourceszOpenAPIProvider._list_resources       DOO**,--r   c                   K   | j                   j                  |      }|y||j                  |j                        sy|S w)zGet a resource by URI.N)r>   ro   r   r   )rX   r   r   r0   s       rd   _get_resourcezOpenAPIProvider._get_resource  sD      ??&&s+wx7G7G'Hr   c                P   K   t        | j                  j                               S w)z<Return all resource templates created from the OpenAPI spec.)r   r?   r   rx   s    rd   _list_resource_templatesz(OpenAPIProvider._list_resource_templates  r   r   c                  K   | j                   j                         D cg c]  }|j                  |      | }}|sy|+|D cg c]   }|j                  |j                        s|" }}|syt	        |t
              S c c}w c c}w w)z3Get a resource template that matches the given URI.N)key)r?   r   r   r   maxr#   )rX   r   r   tmatchings        rd   _get_resource_templatez&OpenAPIProvider._get_resource_template  s       $557V7!199S>;UA7V#+J8awqyy/I8HJ8!122 W Ks&   B
B B B
 B&B* B
c                   K   g S w)z3Return empty list - OpenAPI doesn't create prompts.r   rx   s    rd   _list_promptszOpenAPIProvider._list_prompts       	   c                   K   g S w)z;Return empty list - OpenAPI components don't support tasks.r   rx   s    rd   	get_taskszOpenAPIProvider.get_tasks  r   r   )N)rY   dict[str, Any]rZ   zhttpx.AsyncClient | Noner(   zlist[RouteMap] | Noner)   zRouteMapFn | Noner*   zComponentFn | Noner+   dict[str, str] | Noner,   zset[str] | Noner-   bool)rY   r   returnzhttpx.AsyncClient)r   zAsyncIterator[None])r]   r   r   r   r   r   )rK   r   r   z:Literal['tool', 'resource', 'resource_template', 'prompt']r   r   )r]   r   rK   r   r,   zset[str]r   None)r   zSequence[Tool])rK   r   r   VersionSpec | Noner   zTool | None)r   zSequence[Resource])r   r   r   r   r   zResource | None)r   zSequence[ResourceTemplate])r   r   r   r   r   zResourceTemplate | None)r   zSequence[Prompt])r   zSequence[FastMCPComponent])__name__
__module____qualname____doc__r6   classmethodr8   r   ry   rM   r   rQ   rS   rU   r   r   r   r   r   r   r   r   __classcell__)rc   s   @rd   r$   r$   3   s   , ,0_P
 -1*./3+/ $ $_P$_P )_P
 *_P (_P -_P )_P _P _PB M M   HL/D	* S 
	 2&2& 2& 	2&
 
2&h!6!6 !6 	!6
 
!6F=:=: =: 	=:
 
=:F*
 8<		"4			.
 7;		!3			.
 7;33!33	 3rv   ):r   
__future__r   collectionsr   collections.abcr   r   
contextlibr   typingr   r	   r
   rr   jsonschema_pathr   fastmcp.promptsr   fastmcp.resourcesr   r   fastmcp.server.providers.baser   +fastmcp.server.providers.openapi.componentsr   r   r   r   r   (fastmcp.server.providers.openapi.routingr   r   r   r   r   r   fastmcp.tools.baser   fastmcp.utilities.componentsr   fastmcp.utilities.loggingr   fastmcp.utilities.openapir   r   r    "fastmcp.utilities.openapi.directorr!   fastmcp.utilities.versionsr"   r#   __all__r   rD   r&   __annotations__r$   r   rv   rd   <module>r      s    N "  3 * % %  & " 8 2   $ 9 0 
 ? D  
H	 Ah Arv   