
    k7i9                       S r SSKJr  SSKrSSKrSSKJr  SSKJr  SSK	J
r
Jr  SSKJrJr  SSKJr  SS	KJrJrJr  SS
KJr  SSKJr  SSKJr  SSKJr  SSKJrJr  SS jr SS jr!SS jr" " S S\5      r " S S\5      r#g)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_typeadapterc                    [         R                  " SU 5      nU(       a>  UR                  S5      R                  S5       Vs1 s H  o"R	                  5       iM     sn$ [        5       $ s  snf )zFExtract query parameter names from RFC 6570 `{?param1,param2}` syntax.z\{\?([^}]+)\}   ,)researchgroupsplitstripset)uri_templatematchps      T/home/james-whalen/.local/lib/python3.13/site-packages/fastmcp/resources/template.pyextract_query_paramsr!      sP    II&5E#(;;q>#7#7#<=#<a	#<==5L >s   A'c                   [         R                  " SSU 5      n[         R                  " SU5      nSnU H~  nUR                  S5      (       aL  UR	                  S5      (       a6  USS nUR	                  S5      (       a  US	S nUS
U S3-  nMZ  US
U S3-  nMe  U[         R
                  " U5      -  nM     [         R                  " SU S35      $ )zBuild 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_regexr5   %   s      VVNBAHH^%;<EG??3DMM#$6$6":D}}S!!CRyT$t,,T$w//ryy&G  ::'!n%%    c                f   U R                  S5      u  p#n[        U5      nUR                  U5      nU(       d  gUR                  5       R	                  5        VVs0 s H  u  pxU[        U5      _M     n	nnU(       a/  [        U5      n
[        U5      nU
 H  nX;   d  M
  X   S   X'   M     U	$ s  snnf )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   )	partitionr5   r   	groupdictitemsr   r!   r   )urir   uri_path_query_stringregexr   kvparamsquery_param_namesparsed_queryr4   s                r    match_uri_templaterF   ?   s     !$c 2H %EKK!E(-(9(?(?(AB(Aam(AFB 0>-%D#+1!4 &
 M Cs   B-c                    ^  \ rS rSr% Sr\" SS9rS\S'   \" SSS	9rS\S
'   \" SS9r	S\S'   \" SSS	9r
S\S'   S!S jrS"U 4S jjrS"U 4S jjr\         S#                       S$S jj5       r\" S
SS9\S%S j5       5       rS&S jrS'S jrS(S jrSS.     S)S jjr\S*S j5       r\S!S j5       rS rU =r$ )+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)defaultrJ   	mime_typez#JSON schema for function parametersdict[str, Any]
parametersNz2Optional annotations about the resource's behaviorAnnotations | Noner   c           
         U R                   R                   SU R                  < SU R                  < SU R                  < SU R
                   S3
$ )Nz(uri_template=z, name=z, description=z, tags=))	__class____name__r   r4   rJ   tagsselfs    r    __repr__ResourceTemplate.__repr__n   s~    ..))*.9J9J8MWUYU^U^Taaopt  qA  qA  pD  DK  LP  LU  LU  KV  VW  X  	Xr6   c                x   > [         TU ]  5          [        5       nUR                  5         g ! [         a     g f = fN)superenabler   _queue_resource_list_changedRuntimeErrorrX   contextrT   s     r    r^   ResourceTemplate.enableq   s7    	!mG002 		   , 
99c                x   > [         TU ]  5          [        5       nUR                  5         g ! [         a     g f = fr\   )r]   disabler   r_   r`   ra   s     r    rf   ResourceTemplate.disabley   s7    	!mG002 		rd   c                <    [         R                  U UUUUUUUUU	U
S9$ )Nfnr   r4   titlerJ   iconsrN   rV   enabledr   meta)FunctionResourceTemplatefrom_functionri   s              r    rp   ResourceTemplate.from_function   s=     (55%## 6 
 	
r6   before)modec                    U(       a  U$ g)z&Set default MIME type if not provided.rL    )clsrN   s     r    set_default_mime_type&ResourceTemplate.set_default_mime_type   s     r6   c                ,    [        XR                  5      $ )z5Check if URI matches template and extract parameters.)rF   r   )rX   r<   s     r    matchesResourceTemplate.matches   s    !#'8'899r6   c                    #    [        S5      e7f)Read the resource content.z>Subclasses must implement read() or override create_resource())NotImplementedError)rX   	argumentss     r    readResourceTemplate.read   s     !L
 	
s   c           
        ^ ^#    SUU 4S jjn[         R                  " UUT R                  T R                  T R                  T R
                  T R                  S9$ 7f)z>Create a resource from the template with the given parameters.c                 B   >#    TR                  TS9I S h  vN n U $  N7f)N)r   )r   )resultrC   rX   s    r    resource_read_fn:ResourceTemplate.create_resource.<locals>.resource_read_fn   s#     99v966FM 7s   )rj   r<   r4   rJ   rN   rV   rm   )returnstr | bytes)r   rp   r4   rJ   rN   rV   rm   )rX   r<   rC   r   s   ` ` r    create_resource ResourceTemplate.create_resource   sP     	 	
 %%((nnLL
 	
s   AAinclude_fastmcp_metac                  [        UR                  SU R                  5      UR                  SU R                  5      UR                  SU R                  5      UR                  SU R
                  5      UR                  SU R                  5      UR                  SU R                  5      UR                  SU R                  5      UR                  SU R                  US	95      S
9$ )z8Convert the resource template to an MCPResourceTemplate.r4   uriTemplaterJ   mimeTyperk   rl   r   _metar   )r4   r   rJ   r   rk   rl   r   r   )
MCPResourceTemplategetr4   r   rJ   rN   rk   rl   r   get_meta)rX   r   	overridess      r    to_mcp_template ResourceTemplate.to_mcp_template   s     #vtyy1!mT5F5FG!mT5E5EF]]:t~~>--4--4!mT5E5EF--<PQ
 	
r6   c                x    U " UR                   UR                  UR                  UR                  =(       d    S0 S9$ )zJCreates a FastMCP ResourceTemplate from a raw MCP ResourceTemplate object.rL   )r   r4   rJ   rN   rP   )r   r4   rJ   r   )rv   mcp_templates     r    from_mcp_template"ResourceTemplate.from_mcp_template   s=    
 %11""$00"++;|
 	
r6   c                @    U R                   =(       d    U R                  $ )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   rW   s    r    keyResourceTemplate.key   s     yy-D---r6   ru   )r   rK   )r   None	NNNNNNNNNrj   Callable[..., Any]r   rK   r4   
str | Nonerk   r   rJ   r   rl   zlist[Icon] | NonerN   r   rV   zset[str] | Nonerm   bool | Noner   rQ   rn   dict[str, Any] | Noner   ro   )rN   r   r   rK   )r<   rK   r   r   r   rO   r   r   )r<   rK   rC   rO   r   r   )r   r   r   r   r   r   )r   r   r   r
   )rU   
__module____qualname____firstlineno____doc__r   r   __annotations__rN   rP   r   rY   r^   rf   staticmethodrp   r   classmethodrw   rz   r   r   r   r   propertyr   __static_attributes____classcell__)rT   s   @r    r
   r
   ^   s   8RL#  *MIs  "'9"J  ',"V'K# X    "&#' $ $#*.&*


 
 	

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

 

* 

 

 . .r6   r
   c                      \ rS rSr% SrS\S'   S	S jr\         S
                       SS jj5       rSr	g)ro      rI   r   rj   c                0  #    SSK Jn  UR                  5       n[        U R                  US9nU(       a  XC;  a  [        5       X4'   [        R                  " U R                  5      n[        UR                  5       5       H  u  pgXeR                  ;   d  M  [        U[        5      (       d  M-  UR                  U   nUR                  n	U	[        R                  R                  L d	  U	[        L a  Mp   U	[         L a  [!        U5      X6'   M  U	["        L a  [#        U5      X6'   M  U	[$        L a  UR'                  5       S;   X6'   M  M     U R                  " S0 UD6n
[        R,                  " U
5      (       a
  U
I Sh  vN n
U
$ ! [(        [*        4 a     GM  f = f N7f)r}   r   Context
kwarg_type)true1yesNru   )fastmcp.server.contextr   copyr   rj   r   inspect	signaturelistr;   rP   
isinstancerK   
annotation	Parameteremptyintfloatboollower
ValueErrorAttributeErrorisawaitable)rX   r   r   kwargscontext_kwargsig
param_nameparam_valueparamr   r   s              r    r   FunctionResourceTemplate.read   sV    2 !*477wG]8$/MF! ('+FLLN';#J^^+
;0L0Lz2"--
 !2!2!8!88J#<M
!S(-0-=*#u,-2;-?*#t+-8->->-@DX-X* , (<, "6"v&&!\F #N3  "s[   BFF+AF/E<FE<FE<=8F5F6F<FFFFNc                   SSK Jn  U=(       d*    [        USS5      =(       d    UR                  R                  nUS:X  a  [        S5      e[        R                  " U5      nUR                  R                  5        H6  nUR                  [        R                  R                  :X  d  M-  [        S5      e   [        XS9n[        [        R                   " S	U5      5      n[#        U5      nUU-  nU(       d  [        S
5      e[        UR                  R%                  5       5      nU(       a  UR'                  U5        U Vs1 s Hz  nUR                  U   R(                  [        R                  R*                  L d  M9  UR                  U   R                  [        R                  R,                  :w  d  Mp  UU:w  d  Mx  UiM|     nnU Vs1 s Hz  nUR                  U   R(                  [        R                  R*                  Ld  M9  UR                  U   R                  [        R                  R,                  :w  d  Mp  UU:w  d  Mx  UiM|     nnU(       a  UU-
  nU(       a  [        SU S35      eUR/                  U5      (       d  [        SU SU 35      e[1        S UR                  R                  5        5       5      (       d'  UR/                  U5      (       d  [        SU SU 35      eU=(       d    [        R2                  " U5      n[        R4                  " U5      (       d  UR6                  n[9        U[:        5      (       a  UR<                  n[?        U5      nURA                  5       nU(       a  U/OSn[C        UUS9n[E        U5      nU " UUUUUU=(       d    SUUU=(       d
    [        5       U	b  U	OSU
US9$ s  snf s  snf )z"Create a template from a function.r   r   rU   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 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  p   #    U  H,  nUR                   [        R                  R                  :H  v   M.     g 7fr\   )kindr   r   VAR_KEYWORD).0r   s     r    	<genexpr>9FunctionResourceTemplate.from_function.<locals>.<genexpr>j  s,      
0 JJ'++7770s   46zURI parameters z- must be a subset of the function arguments: )prune_paramsrL   T)r   r4   rk   rJ   rl   rN   rj   rP   rV   rm   r   rn   )#r   r   getattrrT   rU   r   r   r   rP   valuesr   r   VAR_POSITIONALr   r   r   findallr!   keysdiscardrM   r   r   issubsetanygetdoc	isroutine__call__r   r   __func__r   json_schemar   r   )rv   rj   r   r4   rk   rJ   rl   rN   rV   rm   r   rn   r   	func_namer   r   r   path_paramsquery_paramsall_uri_paramsfunc_paramsr   required_paramsoptional_paramsinvalid_query_paramstype_adapterrP   r   s                               r    rp   &FunctionResourceTemplate.from_function  s     	3RGB
D9RR\\=R=R	
"KLL #^^**,EzzW..=== R  - +2B "**%6EF+L9$|3OPP#..--/0.
 !
 ~~a ((G,=,=,C,CC  q!&&'*;*;*G*GG  ]"	   	 
 !
 ~~a ((0A0A0G0GG  q!&&'*;*;*G*GG  ]"	   	 
 #//#A # '(<'==vw 
 ''44..??lmxlyz 
  
..0
 
 
 "**;77 %n%55bcnbop  "7W^^B%7   $$Bb,''B-b1!--/
 +8T$ZlK
 2%#/<!&2G#
 	
w

s0   ?8N;;3N;2N;:N;8O 3O 9O O ru   r   r   r   )
rU   r   r   r   r   r   r   r   rp   r   ru   r6   r    ro   ro      s    8&P 
   "&#' $ $#*.&*w
w
 w
 	w

 w
  w
 !w
 w
 w
 w
 (w
 $w
 
"w
 w
r6   ro   )r   rK   r   zset[str])r/   rK   r   z
re.Pattern)r<   rK   r   rK   r   zdict[str, str] | None)$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!   r5   rF   ro   ru   r6   r    <module>r      sk    & "  	 $  * ' =  0 3 9 9&4>M.' M.`e
/ e
r6   