o
    i9                     @  s   d Z ddlmZ ddl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mZ ddlmZ dd	l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mZ d!ddZ d"ddZ!d#ddZ"G dd deZG dd  d eZ#dS )$z Resource template functionality.    )annotationsN)Callable)Any)parse_qsunquote)AnnotationsIcon)ResourceTemplate)Fieldfield_validatorvalidate_call)Resource)get_context)FastMCPComponent)compress_schema)find_kwarg_by_typeget_cached_typeadapteruri_templatestrreturnset[str]c                 C  s0   t d| }|rdd |ddD S t S )zFExtract query parameter names from RFC 6570 `{?param1,param2}` syntax.z\{\?([^}]+)\}c                 S  s   h | ]}|  qS  )strip.0pr   r   `/var/www/html/karishye-ai-python/venv/lib/python3.10/site-packages/fastmcp/resources/template.py	<setcomp>!   s    z'extract_query_params.<locals>.<setcomp>   ,)researchgroupsplitset)r   matchr   r   r   extract_query_params   s   r&   template
re.Patternc                 C  s   t dd| }t d|}d}|D ]6}|dr@|dr@|dd }|dr7|d	d }|d
| d7 }q|d
| d7 }q|t |7 }qt d| dS )a  Build regex pattern for URI template, handling RFC 6570 syntax.

    Supports:
    - `{var}` - simple path parameter
    - `{var*}` - wildcard path parameter (captures multiple segments)
    - `{?var1,var2}` - query parameters (ignored in path matching)
    z\{\?[^}]+\} z(\{[^}]+\}){}r   *Nz(?P<z>.+)z>[^/]+)^$)r    subr#   
startswithendswithescapecompile)r'   template_without_querypartspatternpartnamer   r   r   build_regex%   s   	
r:   uridict[str, str] | Nonec                 C  sz   |  d\}}}t|}||}|sdS dd |  D }|r;t|}t|}	|D ]}
|
|	v r:|	|
 d ||
< q,|S )zMatch URI against template and extract both path and query parameters.

    Supports RFC 6570 URI templates:
    - Path params: `{var}`, `{var*}`
    - Query params: `{?var1,var2}`
    ?Nc                 S  s   i | ]	\}}|t |qS r   )r   )r   kvr   r   r   
<dictcomp>O   s    z&match_uri_template.<locals>.<dictcomp>r   )	partitionr:   r%   	groupdictitemsr&   r   )r;   r   uri_path_query_stringregexr%   paramsquery_param_namesparsed_queryr9   r   r   r   match_uri_template?   s   
rK   c                      s  e Zd ZU dZeddZded< edddZded	< ed
dZded< edddZ	ded< dEddZ
dF fddZdF fddZe									dGdHd(d)Zed	d*d+edId,d-ZdJd/d0ZdKd3d4ZdLd7d8Zdd9dMd>d?ZedNdAdBZedEdCdDZ  ZS )Or	   .A template for dynamically creating resources.z<URI template with parameters (e.g. weather://{city}/current))descriptionr   r   
text/plainz!MIME type of the resource content)defaultrM   	mime_typez#JSON schema for function parametersdict[str, Any]
parametersNz2Optional annotations about the resource's behaviorAnnotations | Noner   r   c              
   C  s.   | j j d| jd| jd| jd| j d
S )Nz(uri_template=z, name=z, description=z, tags=))	__class____name__r   r9   rM   tagsselfr   r   r   __repr__n   s   .zResourceTemplate.__repr__Nonec                   4   t    z
t }|  W d S  ty   Y d S w N)superenabler   _queue_resource_list_changedRuntimeErrorrY   contextrU   r   r   r_   q      
zResourceTemplate.enablec                   r\   r]   )r^   disabler   r`   ra   rb   rd   r   r   rf   y   re   zResourceTemplate.disablefnCallable[..., Any]r9   
str | NonetitlerM   iconslist[Icon] | NonerW   set[str] | Noneenabledbool | Nonemetadict[str, Any] | NoneFunctionResourceTemplatec                 C  s    t j| |||||||||	|
dS )Nrg   r   r9   rj   rM   rk   rP   rW   rn   r   rp   )rr   from_functionrs   r   r   r   rt      s   zResourceTemplate.from_functionbefore)modec                 C  s   |r|S dS )z&Set default MIME type if not provided.rN   r   )clsrP   r   r   r   set_default_mime_type   s   z&ResourceTemplate.set_default_mime_typer;   c                 C  s   t || jS )z5Check if URI matches template and extract parameters.)rK   r   )rY   r;   r   r   r   matches   s   zResourceTemplate.matches	argumentsstr | bytesc                   s
   t d)Read the resource content.z>Subclasses must implement read() or override create_resource())NotImplementedError)rY   rz   r   r   r   read   s   zResourceTemplate.readrH   r   c              	     s4   d fdd}t j||jjjjjdS )z>Create a resource from the template with the given parameters.r   r{   c                    s   j  dI d H } | S )N)rz   )r~   )resultrH   rY   r   r   resource_read_fn   s   z:ResourceTemplate.create_resource.<locals>.resource_read_fn)rg   r;   r9   rM   rP   rW   rn   N)r   r{   )r   rt   r9   rM   rP   rW   rn   )rY   r;   rH   r   r   r   r   create_resource   s   z ResourceTemplate.create_resourceinclude_fastmcp_metar   	overridesr   MCPResourceTemplatec                K  sn   t |d| j|d| j|d| j|d| j|d| j|d| j|d| j|d| j	|d	d
S )z8Convert the resource template to an MCPResourceTemplate.r9   uriTemplaterM   mimeTyperj   rk   r   _metar   )r9   r   rM   r   rj   rk   r   r   )
r   getr9   r   rM   rP   rj   rk   r   get_meta)rY   r   r   r   r   r   to_mcp_template   s   z ResourceTemplate.to_mcp_templatemcp_templatec                 C  s   | |j |j|j|jpdi dS )zJCreates a FastMCP ResourceTemplate from a raw MCP ResourceTemplate object.rN   )r   r9   rM   rP   rR   )r   r9   rM   r   )rw   r   r   r   r   from_mcp_template   s   z"ResourceTemplate.from_mcp_templatec                 C  s   | j p| jS )a*  
        The key of the component. This is used for internal bookkeeping
        and may reflect e.g. prefixes or other identifiers. You should not depend on
        keys having a certain value, as the same tool loaded from different
        hierarchies of servers may have different keys.
        )_keyr   rX   r   r   r   key   s   zResourceTemplate.key)r   r   )r   r[   	NNNNNNNNNrg   rh   r   r   r9   ri   rj   ri   rM   ri   rk   rl   rP   ri   rW   rm   rn   ro   r   rS   rp   rq   r   rr   )rP   ri   r   r   )r;   r   r   rq   rz   rQ   r   r{   )r;   r   rH   rQ   r   r   )r   ro   r   r   r   r   )r   r   r   r	   )rV   
__module____qualname____doc__r
   r   __annotations__rP   rR   r   rZ   r_   rf   staticmethodrt   r   classmethodrx   ry   r~   r   r   r   propertyr   __classcell__r   r   rd   r   r	   ^   sP   
 




r	   c                   @  sF   e Zd ZU dZded< ddd	Ze	
	
	
	
	
	
	
	
	
dd ddZd
S )!rr   rL   rh   rg   rz   rQ   r   r{   c              
     s  ddl m} | }t| j|d}|r||vrt ||< t| j}t|	 D ]Q\}}||j
v rzt|trz|j
| }|j}	|	tjju sI|	tu rJq)z$|	tu rVt|||< n|	tu rat|||< n|	tu rm| dv ||< W q) ttfyy   Y q)w q)| jdi |}
t|
r|
I dH }
|
S )r|   r   Context
kwarg_type)true1yesNr   )fastmcp.server.contextr   copyr   rg   r   inspect	signaturelistrC   rR   
isinstancer   
annotation	Parameteremptyintfloatboollower
ValueErrorAttributeErrorisawaitable)rY   rz   r   kwargscontext_kwargsig
param_nameparam_valueparamr   r   r   r   r   r~      s:   



zFunctionResourceTemplate.readNr   r   r9   ri   rj   rM   rk   rl   rP   rW   rm   rn   ro   r   rS   rp   rq   c                   s  ddl m} |pt|ddp|jj}|dkrtdt|j	 D ]}|j
tjjkr1tdq$t||d ttd	|}t|}||B }|sNtd
tj } r\|   fdd|D } fdd|D }|r|| }|rtd| d||std| d| tdd j	 D s||std| d| |pt|}t|s|j}t|tr|j}t|}| } rΈ gnd}t||d}t|}| ||||||pd|||pt |	dur|	nd|
|dS )z"Create a template from a function.r   r   rV   Nz<lambda>z,You must provide a name for lambda functionsz<Functions with *args are not supported as resource templatesr   z{(\w+)(?:\*)?}z0URI template must contain at least one parameterc                   s@   h | ]}j | jtjju rj | jtjjkr| kr|qS r   rR   rO   r   r   r   kindVAR_KEYWORDr   r   r   r   r   r   K      z9FunctionResourceTemplate.from_function.<locals>.<setcomp>c                   s@   h | ]}j | jtjjurj | jtjjkr| kr|qS r   r   r   r   r   r   r   R  r   zQuery parameters z9 must be optional function parameters with default valueszRequired function arguments z- must be a subset of the URI path parameters c                 s  s    | ]
}|j tjjkV  qd S r]   )r   r   r   r   )r   r   r   r   r   	<genexpr>j  s
    
z9FunctionResourceTemplate.from_function.<locals>.<genexpr>zURI parameters z- must be a subset of the function arguments: )prune_paramsrN   T)r   r9   rj   rM   rk   rP   rg   rR   rW   rn   r   rp   ) r   r   getattrrU   rV   r   r   r   rR   valuesr   r   VAR_POSITIONALr   r$   r    findallr&   keysdiscardissubsetanygetdoc	isroutine__call__r   r   __func__r   json_schemar   r   )rw   rg   r   r9   rj   rM   rk   rP   rW   rn   r   rp   r   	func_namer   path_paramsquery_paramsall_uri_paramsfunc_paramsrequired_paramsoptional_paramsinvalid_query_paramstype_adapterrR   r   r   r   r   rt     s   







z&FunctionResourceTemplate.from_functionr   r   r   )rV   r   r   r   r   r~   r   rt   r   r   r   r   rr      s   
 
(rr   )r   r   r   r   )r'   r   r   r(   )r;   r   r   r   r   r<   )$r   
__future__r   r   r    collections.abcr   typingr   urllib.parser   r   	mcp.typesr   r   r	   r   pydanticr
   r   r   fastmcp.resources.resourcer   fastmcp.server.dependenciesr   fastmcp.utilities.componentsr   fastmcp.utilities.json_schemar   fastmcp.utilities.typesr   r   r&   r:   rK   rr   r   r   r   r   <module>   s*    


 