
    Ki<                       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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mZ ddlmZ ddlmZ ddlm Z  ddl!m"Z" ddZ#ddZ$ddZ% G d de      Z G d de      Z&y)z Resource template functionality.    )annotationsN)Callable)	AnnotatedAny)parse_qsunquote)AnnotationsIcon)ResourceTemplate)Fieldfield_validatorvalidate_call)Resource)get_contextwithout_injected_parameters
TaskConfig)FastMCPComponent)compress_schema)get_cached_typeadapterc                    t        j                  d|       }|r<|j                  d      j                  d      D ch c]  }|j	                          c}S t               S c c}w )zFExtract query parameter names from RFC 6570 `{?param1,param2}` syntax.z\{\?([^}]+)\}   ,)researchgroupsplitstripset)uri_templatematchps      f/home/jay/workspace/scripts/.codegraph-venv/lib/python3.12/site-packages/fastmcp/resources/template.pyextract_query_paramsr$      sL    II&5E#(;;q>#7#7#<=a	==5L >s   Ac                r   t        j                  dd|       }t        j                  d|      }d}|D ]k  }|j                  d      r@|j	                  d      r/|dd }|j	                  d      r|d	d }|d
| dz  }J|d
| dz  }T|t        j
                  |      z  }m t        j                  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)templatetemplate_without_querypartspatternpartnames         r#   build_regexr8   #   s      VVNBAHH^%;<EG 	'??3DMM#$6":D}}S!CRyT$t,,T$w//ryy&G	' ::'!n%%    c                L   | j                  d      \  }}}t        |      }|j                  |      }|sy|j                         j	                         D ci c]  \  }}|t        |       }	}}|r-t        |      }
t        |      }|
D ]  }||v s||   d   |	|<    |	S c c}}w )zMatch URI against template and extract both path and query parameters.

    Supports RFC 6570 URI templates:
    - Path params: `{var}`, `{var*}`
    - Query params: `{?var1,var2}`
    ?Nr   )	partitionr8   r!   	groupdictitemsr   r$   r   )urir    uri_path_query_stringregexr!   kvparamsquery_param_namesparsed_queryr7   s                r#   match_uri_templaterI   =   s     !$c 2Ha %EKK!E(-(9(?(?(AB1amBFB 0>-% 	5D|#+D1!4t	5
 M Cs   B c                      e Zd ZU dZ ed      Zded<    edd      Zded	<    ed
      Zded<    edd      Z	ded<   ddZ
d  fdZd  fdZe	 	 	 	 	 	 	 	 	 	 d!	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d"d       Z ed	d      ed#d              Zd$dZd%dZd&dZdd	 	 	 	 	 d'dZed(d       Zedd       Z xZS ))r   .A template for dynamically creating resources.z<URI template with parameters (e.g. weather://{city}/current))descriptionstrr    
text/plainz!MIME type of the resource content)defaultrL   	mime_typez#JSON schema for function parametersdict[str, Any]
parametersNz2Optional annotations about the resource's behaviorAnnotations | Noner   c           
         | j                   j                   d| j                  d| j                  d| j                  d| j
                   d
S )Nz(uri_template=z, name=z, description=z, tags=))	__class____name__r    r7   rL   tagsselfs    r#   __repr__zResourceTemplate.__repr__l   s~    ..))*.9J9J8MWUYU^U^Taaopt  qA  qA  pD  DK  LP  LU  LU  KV  VW  X  	Xr9   c                v    t         |           	 t               }|j                          y # t        $ r Y y w xY wN)superenabler   _queue_resource_list_changedRuntimeErrorrZ   contextrV   s     r#   r_   zResourceTemplate.enableo   s7    	!mG002 		   , 	88c                v    t         |           	 t               }|j                          y # t        $ r Y y w xY wr]   )r^   disabler   r`   ra   rb   s     r#   rf   zResourceTemplate.disablew   s7    	!mG002 		rd   c                D    t         j                  | |||||||||	|
|      S )Nfnr    r7   titlerL   iconsrP   rX   enabledr   metatask)FunctionResourceTemplatefrom_functionrh   s               r#   rp   zResourceTemplate.from_function   s@     (55%## 6 
 	
r9   beforemodec                    |r|S y)z&Set default MIME type if not provided.rN    )clsrP   s     r#   set_default_mime_typez&ResourceTemplate.set_default_mime_type   s     r9   c                .    t        || j                        S )z5Check if URI matches template and extract parameters.)rI   r    )rZ   r?   s     r#   matcheszResourceTemplate.matches   s    !#t'8'899r9   c                    K   t        d      w)Read the resource content.z>Subclasses must implement read() or override create_resource()NotImplementedError)rZ   	argumentss     r#   readzResourceTemplate.read   s     !L
 	
   c                    K   t        d      w)zCreate a resource from the template with the given parameters.

        The base implementation does not support background tasks.
        Use FunctionResourceTemplate for task support.
        z[Subclasses must implement create_resource(). Use FunctionResourceTemplate for task support.r|   )rZ   r?   rF   s      r#   create_resourcez ResourceTemplate.create_resource   s      "=
 	
r   include_fastmcp_metac                  t        |j                  d| j                        |j                  d| j                        |j                  d| j                        |j                  d| j
                        |j                  d| j                        |j                  d| j                        |j                  d| j                        |j                  d| j                  |	            
      S )z8Convert the resource template to an SDKResourceTemplate.r7   uriTemplaterL   mimeTyperj   rk   r   _metar   )r7   r   rL   r   rj   rk   r   r   )
SDKResourceTemplategetr7   r    rL   rP   rj   rk   r   get_meta)rZ   r   	overridess      r#   to_mcp_templatez ResourceTemplate.to_mcp_template   s     #vtyy1!mT5F5FG!mT5E5EF]]:t~~>--4--4!mT5E5EF--<PQ
 	
r9   c                t     | |j                   |j                  |j                  |j                  xs di       S )zJCreates a FastMCP ResourceTemplate from a raw MCP ResourceTemplate object.rN   )r    r7   rL   rP   rR   )r   r7   rL   r   )rv   mcp_templates     r#   from_mcp_templatez"ResourceTemplate.from_mcp_template   s=    
 %11""$00"++;|
 	
r9   c                6    | j                   xs | 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    rY   s    r#   keyzResourceTemplate.key   s     yy-D---r9   )returnrM   )r   None
NNNNNNNNNNri   Callable[..., Any]r    rM   r7   
str | Nonerj   r   rL   r   rk   zlist[Icon] | NonerP   r   rX   zset[str] | Nonerl   bool | Noner   rS   rm   dict[str, Any] | Nonern   zbool | TaskConfig | Noner   ro   )rP   r   r   rM   )r?   rM   r   r   r~   rQ   r   str | bytesr?   rM   rF   rQ   r   r   )r   r   r   r   r   r   )r   r   r   r   )rW   
__module____qualname____doc__r   r    __annotations__rP   rR   r   r[   r_   rf   staticmethodrp   r   classmethodrw   ry   r   r   r   r   propertyr   __classcell__)rV   s   @r#   r   r   \   s   8RL#  *MIs  "'9"J  ',"V'K# X    "&#' $ $#*.&*)-


 
 	

  
 !
 
 
 
 (
 $
 '
 
"
 
: [x0  1:
	
 -1
 *
 	

 

* 

 

 . .r9   r   c                      e Zd ZU dZded<    ed       Zded<   ddZdd	Ze		 	 	 	 	 	 	 	 	 	 d	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dd       Z
y
)ro   rK   r   ri   c                     t        d      S )N	forbiddenrr   r   ru   r9   r#   <lambda>z!FunctionResourceTemplate.<lambda>   s    jk&B r9   )default_factoryz_Annotated[TaskConfig, Field(description='Background task execution configuration (SEP-1686).')]task_configc           
         K   d fd}t        j                  || j                   j                   j                   j
                   j                   j                        S w)z>Create a resource from the template with the given parameters.c                 H   K   j                         d {   } | S 7 w)N)r~   )r   )resultrF   rZ   s    r#   resource_read_fnzBFunctionResourceTemplate.create_resource.<locals>.resource_read_fn   s$     99v966FM 7s   " ")ri   r?   r7   rL   rP   rX   rl   rn   )r   r   )r   rp   r7   rL   rP   rX   rl   r   )rZ   r?   rF   r   s   ` ` r#   r   z(FunctionResourceTemplate.create_resource   sU     	
 %%((nnLL!!	
 		
s   A!A%c                  K   |j                         }t        j                  | j                        }t	        |j                               D ]  \  }}||j                  v st        |t              s&|j                  |   }|j                  }|t        j                  j                  u s|t        u rf	 |t        u rt        |      ||<   n4|t        u rt        |      ||<   n|t        u r|j                         dv ||<     | j                  di |}t        j$                  |      r
| d{   }|S # t         t"        f$ r Y w xY w7 w)r{   )true1yesNru   )copyinspect	signatureri   listr>   rR   
isinstancerM   
annotation	Parameteremptyintfloatboollower
ValueErrorAttributeErrorisawaitable)	rZ   r~   kwargssig
param_nameparam_valueparamr   r   s	            r#   r   zFunctionResourceTemplate.read  s5     !('+FLLN'; 	#JS^^+
;0Lz2"--
!2!2!8!88J#<M!S(-0-=z*#u,-2;-?z*#t+-8->->-@DX-Xz*	( "6"v&!\F #N3  "sD   AE	 E	1A E	2AD2=.E	+E,E	2EE	EE	Nc                B   |xs% t        |dd      xs |j                  j                  }|dk(  rt        d      t	        j
                  |      }|j                  j                         D ]4  }|j                  t        j                  j                  k(  s+t        d       t        t        j                  d|            }t        |      }||z  }|st        d      t        |      }t	        j
                  |      }t        |j                  j!                               }|D ch c]k  }|j                  |   j"                  t        j                  j$                  u r6|j                  |   j                  t        j                  j&                  k7  r|m }}|D ch c]k  }|j                  |   j"                  t        j                  j$                  ur6|j                  |   j                  t        j                  j&                  k7  r|m }}|r||z
  }|rt        d| d	      |j)                  |      st        d
| d|       t+        d |j                  j                         D              s"|j)                  |      st        d| d|       |xs t	        j,                  |      }|t/        d      }n(t1        |t2              rt/        j4                  |      }n|}|j7                  ||       t	        j8                  |      s|j:                  }t1        |t<              r|j>                  }t        |      }tA        |      }|jC                         }tE        |d      }tG        |      } | ||||||xs d|||xs
 t               |	|	nd|
||      S c c}w c c}w )z"Create a template from a function.rW   Nz<lambda>z,You must provide a name for lambda functionsz<Functions with *args are not supported as resource templatesz{(\w+)(?:\*)?}z0URI template must contain at least one parameterz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              3  j   K   | ]+  }|j                   t        j                  j                  k(   - y wr]   )kindr   r   VAR_KEYWORD).0r   s     r#   	<genexpr>z9FunctionResourceTemplate.from_function.<locals>.<genexpr>l  s-      
 JJ'++777
s   13zURI parameters z- must be a subset of the function arguments: r   rr   T)prune_titlesrN   )r    r7   rj   rL   rk   rP   ri   rR   rX   rl   r   rm   r   )$getattrrV   rW   r   r   r   rR   valuesr   r   VAR_POSITIONALr   r   findallr$   r   keysrO   r   r   issubsetanygetdocr   r   r   	from_boolvalidate_function	isroutine__call__r   __func__r   json_schemar   r   )rv   ri   r    r7   rj   rL   rk   rP   rX   rl   r   rm   rn   	func_namer   r   path_paramsquery_paramsall_uri_params
wrapper_fnuser_sigfunc_paramsr"   required_paramsoptional_paramsinvalid_query_paramsr   type_adapterrR   s                                r#   rp   z&FunctionResourceTemplate.from_function"  s   $ RGB
D9RR\\=R=R	
"KLL #^^**, 	EzzW..=== R 	 "**%6EF+L9$|3OPP 14
$$Z0(--2245
 !
""1%--1B1B1H1HH##A&++w/@/@/L/LL 
 
 !
""1%--W5F5F5L5LL##A&++w/@/@/L/LL 
 
 #//#A # '(<'==vw 
 ''4..??lmxlyz 
  
..0
 
 "**;7 %n%55bcnbop  "7W^^B%7 <$+6Kd#$..t4KK%%b)4   $Bb,'B04
-j9!--/
$ZdC
 :&%#/<!&2G##
 	
A

s   #A0NA0Nr   r   r   r   )rW   r   r   r   r   r   r   r   r   r   rp   ru   r9   r#   ro   ro      s    8 	BC   D

&> 
   "&#' $ $#*.&*)-z
z
 z
 	z

 z
  z
 !z
 z
 z
 z
 (z
 $z
 'z
 
"z
 z
r9   ro   )r    rM   r   zset[str])r2   rM   r   z
re.Pattern)r?   rM   r    rM   r   zdict[str, str] | None)'r   
__future__r   r   r   collections.abcr   typingr   r   urllib.parser   r   	mcp.typesr	   r
   r   r   pydanticr   r   r   fastmcp.resources.resourcer   fastmcp.server.dependenciesr   r   fastmcp.server.tasks.configr   fastmcp.utilities.componentsr   fastmcp.utilities.json_schemar   fastmcp.utilities.typesr   r$   r8   rI   ro   ru   r9   r#   <module>r      sl    & "  	 $ ! * ' =  0 P 2 9 9 :&4>H.' H.Vv
/ v
r9   