
    kKjg                    l   d Z ddlmZ ddlZddlZddlZddlmZ ddlm	Z	m
Z
mZmZ ddlmZmZmZ ddlZddlmZmZ ddlmZ e	r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!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l/m0Z0 ddZ1ddZ2ddZ3ddZ4 G d de'      Z G d de      Z5y) z Resource template functionality.    )annotationsN)Callable)TYPE_CHECKINGAnyClassVaroverload)parse_qsquoteunquote)AnnotationsIcon)SkipJsonSchema)Docket)	Execution)ResourceTemplate)Fieldfield_validatorvalidate_call)ResourceResourceResult)	AuthCheck)FastMCPComponent)compress_schema)resolve_ui_mime_type)
TaskConfigTaskMeta)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.\{\?([^}]+)\}   ,)researchgroupsplitstripset)uri_templatematchps      k/Users/ahmed/devFolder/Ultron/claude-voice/.venv/lib/python3.12/site-packages/fastmcp/resources/template.pyextract_query_paramsr,   #   sR    II&5E#(;;q>#7#7#<=#<a	#<==5L >s   Ac                   t        j                  dd|       }t        j                  d|      }d}|D ]  }|j                  d      rd|j	                  d      rS|dd }|j	                  d      r!|d	d }|j                  d
d      }|d| dz  }\|j                  d
d      }|d| dz  }x|t        j                  |      z  } 	 t        j                  d| d      S # t         j                  $ r Y y	w xY w)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)

    Hyphens in parameter names are normalized to underscores in regex group
    names so that matched groups are valid Python identifiers.

    Returns None if the template produces an invalid regex (e.g. parameter
    names with leading digits or duplicates from a remote server).
    z\{\?[^}]+\} z(\{[^}]+\}){}r    *N-_z(?P<z>.+)z>[^/]+)^$)	r"   subr%   
startswithendswithreplaceescapecompileerror)templatetemplate_without_querypartspatternpartnamer$   s          r+   build_regexrD   +   s      VVNBAHH^%;<EG??3DMM#$6":D}}S!CRyS#.T%--S#.T%00ryy&G zzAgYa.))88 s   C C43C4c                   | j                  d      \  }}}t        |      }|y|j                  |      }|sy|j                         j	                         D ci c]  \  }}|t        |       }	}}|rFt        |      }
t        |d      }|
D ])  }||v s|j                  d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}`
    ?NT)keep_blank_valuesr3   r4   r   )		partitionrD   r)   	groupdictitemsr   r,   r	   r:   )urir(   uri_pathr4   query_stringregexr)   kvparamsquery_param_namesparsed_queryrC   keys                 r+   match_uri_templaterU   P   s     !$c 2Ha %E}KK!E(-(9(?(?(AB(A1am(AFB 0>  E%D|# ll3,f$".t"4Q"7F3K & M% Cs   B<c                |   | }j                         D ]  \  }}t        |      }t        |d      }t        |d      }|g}|j                  dd      }	|	|k7  r|j	                  |	       |D ].  }
|j                  d|
 d|      }|j                  d|
 d|      }0  dfd	}t        j                  d
||      }|S )u   Expand a URI template with parameters — inverse of `match_uri_template`.

    Supports the same RFC 6570 subset:
    - Path params: `{var}`, `{var*}`
    - Query params: `{?var1,var2}`
    r.   )safe/r4   r3   r/   r0   z*}c                   | j                  d      j                  d      D cg c]  }|j                          }}g }|D ]  }|j                  dd      }|v r5|j	                  t        |       dt        t        |                       N|v sS|j	                  t        |       dt        t        |                        |rddj                  |      z   S yc c}w )	Nr    r!   r3   r4   =rF   &r.   )r$   r%   r&   r:   appendr
   strjoin)r)   nnamesr@   rC   underscoredrQ   s         r+   _expand_query_blockz0expand_uri_template.<locals>._expand_query_block   s    $)KKN$8$8$=>$=q$=>D,,sC0Kv~d}AeCt4E.F-GHI&d}AeC{8K4L.M-NOP  %(( ?s   C!r   )r)   zre.Match[str]returnr]   )rJ   r]   r
   r:   r\   r"   r7   )r(   rQ   resultrT   value	value_strsimplewildcardforms
hyphenatedformrb   s    `          r+   expand_uri_templaterl   w   s     F lln
UJ	yr*-[[c*
LL$D^^bbM6:F^^bcNH=F  % VV$&96BFM    c                  >    e Zd ZU dZdZded<    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<    eddd      Zded<   d,dZe	 	 	 	 	 	 	 	 	 	 	 d-	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d.d       Z edd      ed/d              Zd0dZd1dZd2d Ze	 d3	 	 	 	 	 	 	 d4d!       Ze	 	 	 	 	 	 	 	 d5d"       Z	 d3	 	 	 	 	 	 	 d6d#Zd7d$Z	 	 	 	 d8d%Zed9d&       Zed,d'       Zd:d(Zddd)	 	 	 	 	 	 	 	 	 	 	 d;d*Zd< fd+Z xZS )=r   .A template for dynamically creating resources.r>   zClassVar[str]
KEY_PREFIXz<URI template with parameters (e.g. weather://{city}/current))descriptionr]   r(   
text/plainz!MIME type of the resource content)defaultrq   	mime_typez#JSON schema for function parametersdict[str, Any]
parametersNz2Optional annotations about the resource's behaviorAnnotations | Noner   z/Authorization checks for this resource templateT)rs   rq   excludez2SkipJsonSchema[AuthCheck | list[AuthCheck] | None]authc           
         | j                   j                   d| j                  d| j                  d| j                  d| j
                   d
S )Nz(uri_template=z, name=z, description=z, tags=))	__class____name__r(   rC   rq   tags)selfs    r+   __repr__zResourceTemplate.__repr__   s~    ..))*.9J9J8MWUYU^U^Taaopt  qA  qA  pD  DK  LP  LU  LU  KV  VW  X  	Xrm   c                F    t         j                  | |||||||||	|
||      S )Nfnr(   rC   versiontitlerq   iconsrt   r~   r   metataskry   )FunctionResourceTemplatefrom_functionr   s                r+   r   zResourceTemplate.from_function   sC      (55%## 6 
 	
rm   beforemodec                    |r|S y)z&Set default MIME type if not provided.rr    )clsrt   s     r+   set_default_mime_typez&ResourceTemplate.set_default_mime_type   s     rm   c                .    t        || j                        S )z5Check if URI matches template and extract parameters.)rU   r(   )r   rK   s     r+   matcheszResourceTemplate.matches   s    !#t'8'899rm   c                    K   t        d      w)Read the resource content.z>Subclasses must implement read() or override create_resource()NotImplementedError)r   	argumentss     r+   readzResourceTemplate.read   s     !L
 	
   c                <    t        |t              r|S t        |      S )an  Convert a raw result to ResourceResult.

        This is used in two contexts:
        1. In _read() to convert user function return values to ResourceResult
        2. In tasks_result_handler() to convert Docket task results to ResourceResult

        Handles ResourceResult passthrough and converts raw values using
        ResourceResult's normalization.
        )
isinstancer   )r   	raw_values     r+   convert_resultzResourceTemplate.convert_result   s!     i0 i((rm   c                   K   y wNr   r   rK   rQ   	task_metas       r+   _readzResourceTemplate._read           c                   K   y wr   r   r   s       r+   r   zResourceTemplate._read        &)r   c                   K   ddl m}  || d||       d{   }|r|S | j                  ||       d{   }|j                          d{   }| j	                  |      S 7 K7 /7 w)a  Server entry point that handles task routing.

        This allows ANY ResourceTemplate subclass to support background execution
        by setting task_config.mode to "supported" or "required". The server calls
        this method instead of create_resource()/read() directly.

        Args:
            uri: The concrete URI being read
            params: Template parameters extracted from the URI
            task_meta: If provided, execute as a background task and return
                CreateTaskResult. If None (default), execute synchronously and
                return ResourceResult.

        Returns:
            ResourceResult when task_meta is None.
            CreateTaskResult when task_meta is provided.

        Subclasses can override this to customize task routing behavior.
        For example, FastMCPProviderResourceTemplate overrides to delegate to child
        middleware without submitting to Docket.
        r   check_background_taskr>   	component	task_typer   r   N)fastmcp.server.tasks.routingr   create_resourcer   r   )r   rK   rQ   r   r   task_resultresourcerd   s           r+   r   zResourceTemplate._read  st     0 	G1jFi
 
  --c6::}}&""6**
 ;&s1   A*A$A*A&A*A(A*&A*(A*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   )r   rK   rQ   s      r+   r   z ResourceTemplate.create_resource3  s      "=
 	
r   c                   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.rC   uriTemplaterq   mimeTyper   r   r   _meta)rC   r   rq   r   r   r   r   r   )
SDKResourceTemplategetrC   r(   rq   rt   r   r   r   get_meta)r   	overridess     r+   to_mcp_templatez ResourceTemplate.to_mcp_template>  s     #vtyy1!mT5F5FG!mT5E5EF]]:t~~>--4--4!mT5E5EF--
 	
rm   c                t     | |j                   |j                  |j                  |j                  xs di       S )zJCreates a FastMCP ResourceTemplate from a raw MCP ResourceTemplate object.rr   )r(   rC   rq   rt   rv   )r   rC   rq   r   )r   mcp_templates     r+   from_mcp_templatez"ResourceTemplate.from_mcp_templateQ  s=    
 %11""$00"++;|
 	
rm   c                b    | j                  | j                        }| d| j                  xs d S )z1The globally unique lookup key for this template.@r.   )make_keyr(   r   )r   base_keys     r+   rT   zResourceTemplate.key^  s3     ==!2!231T\\/R011rm   c                    | j                   j                         sy|j                  | j                  | j                  g       yz<Register this template with docket for background execution.N)r`   )task_configsupports_tasksregisterr   rT   r   dockets     r+   register_with_docketz%ResourceTemplate.register_with_docketd  s1    ..0		$((4rm   fn_keytask_keyc               ~   K   |xs | j                   }|r||d<     |j                  |fi ||       d{   S 7 w)ak  Schedule this template for background execution via docket.

        Args:
            docket: The Docket instance
            params: Template parameters
            fn_key: Function lookup key in Docket registry (defaults to self.key)
            task_key: Redis storage key for the result
            **kwargs: Additional kwargs passed to docket.add()
        rT   NrT   addr   r   rQ   r   r   kwargs
lookup_keys          r+   add_to_docketzResourceTemplate.add_to_docketj  sE     $ 'txx
$F5M5ZVZZ
5f5f====   4=;=c                ,    t         |          dddz  S )Nresource_templateLocalProvider)zfastmcp.component.typezfastmcp.provider.type)superget_span_attributes)r   r|   s    r+   r   z$ResourceTemplate.get_span_attributes  s#    w*,&9%40
 
 	
rm   )rc   r]   NNNNNNNNNNNr   zCallable[..., Any]r(   r]   rC   
str | Noner   zstr | int | Noner   r   rq   r   r   zlist[Icon] | Nonert   r   r~   zset[str] | Noner   rw   r   dict[str, Any] | Noner   zbool | TaskConfig | Nonery   z"AuthCheck | list[AuthCheck] | Nonerc   r   )rt   r   rc   r]   )rK   r]   rc   r   r   ru   rc   str | bytes | ResourceResult)r   r   rc   r   r   rK   r]   rQ   ru   r   Nonerc   r   rK   r]   rQ   ru   r   r   rc   zmcp.types.CreateTaskResultrK   r]   rQ   ru   r   zTaskMeta | Nonerc   z+ResourceResult | mcp.types.CreateTaskResultrK   r]   rQ   ru   rc   r   )r   r   rc   r   )r   r   rc   r   r   r   rc   r   r   r   rQ   ru   r   r   r   r   r   r   rc   r   )rc   ru   ) r}   
__module____qualname____doc__rp   __annotations__r   r(   rt   rv   r   ry   r   staticmethodr   r   classmethodr   r   r   r   r   r   r   r   r   propertyrT   r   r   r   __classcell__)r|   s   @r+   r   r      s   8 *J*RL#  *MIs  "'9"J  ',"V'K#  @EE@D
< X   $( "&#' $ $*.&*)-37


 
 "	

 
  
 !
 
 
 (
 $
 '
 1
 
"
 
> [x0  1:
)  BF .;?	  )) .);C)	#) )
 NR$+$+ .$+;J$+	4$+L	


 

& 

 

 2 2
5 "#>> >
 > > > 
>.
 
rm   r   c                     e Zd ZU dZded<   e	 d	 	 	 	 	 	 	 dd       Ze	 	 	 	 	 	 	 	 dd       Z	 d	 	 	 	 	 	 	 ddZddZdd	Zdd
Z	ddd	 	 	 	 	 	 	 	 	 	 	 ddZ
e	 	 	 	 	 	 	 	 	 	 	 d	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dd       Zy)r   ro   z"SkipJsonSchema[Callable[..., Any]]r   Nc                   K   y wr   r   r   s       r+   r   zFunctionResourceTemplate._read  r   r   c                   K   y wr   r   r   s       r+   r   zFunctionResourceTemplate._read  r   r   c                   K   ddl m}  || d||       d{   }|r|S | j                  |       d{   }| j                  |      S 7 37 w)a  Optimized server entry point that skips ephemeral resource creation.

        For FunctionResourceTemplate, we can call read() directly instead of
        creating a temporary resource, which is more efficient.

        Args:
            uri: The concrete URI being read
            params: Template parameters extracted from the URI
            task_meta: If provided, execute as a background task and return
                CreateTaskResult. If None (default), execute synchronously and
                return ResourceResult.

        Returns:
            ResourceResult when task_meta is None.
            CreateTaskResult when task_meta is provided.
        r   r   r>   r   Nr   )r   r   r   r   )r   rK   rQ   r   r   r   rd   s          r+   r   zFunctionResourceTemplate._read  s`     & 	G1jFi
 
  yy6y22""6**
 3s   AAAAAAc                &   K   d fd}t        j                  || j                   j                   j                   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)Nr   )r   )rd   rQ   r   s    r+   resource_read_fnzBFunctionResourceTemplate.create_resource.<locals>.resource_read_fn  s$     99v966FM 7s   " ")r   rK   rC   rq   rt   r~   r   r   r   r   r   ry   )rc   r   )r   r   rC   rq   rt   r~   r   r   r   r   r   ry   )r   rK   rQ   r   s   ` ` r+   r   z(FunctionResourceTemplate.create_resource  ss     	
 %%((nn((****!!
 	
s   BB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        |      ||<   nT|t        u rt        |      ||<   n=|t        u r5|j                         }|dv rd||<   n|dv rd||<   nt!        d| d|        | j                  di |}	t        j$                  |	      r
|	 d{   }	|	S # t         t"        f$ r  w xY w7 w)	r   )true1yesT)false0noFzInvalid boolean value for z: Nr   )copyinspect	signaturer   listrJ   rv   r   r]   
annotation	Parameteremptyintfloatboollower
ValueErrorAttributeErrorisawaitable)
r   r   r   sig
param_nameparam_valueparamr  r	  rd   s
             r+   r   zFunctionResourceTemplate.read  sh     !('+FLLN';#JS^^+
;0Lz2"--
!2!2!8!88J#<M!S(-0-=z*#u,-2;-?z*#t+ + 1 1 3 $8815F:."&::16F:.","<ZL;/ Z# ) (<8 "6"v&!\F #N3  "s8   AE( E(1A E(2A+E.E(E&E(E##E(c                    | j                   j                         sy|j                  | j                  | j                  g       yr   )r   r   r   r   rT   r   s     r+   r   z-FunctionResourceTemplate.register_with_docket  s1    ..0z2rm   r   c               ~   K   |xs | j                   }|r||d<     |j                  |fi |di | d{   S 7 w)a  Schedule this template for background execution via docket.

        FunctionResourceTemplate splats the params dict since .fn expects **kwargs.

        Args:
            docket: The Docket instance
            params: Template parameters
            fn_key: Function lookup key in Docket registry (defaults to self.key)
            task_key: Redis storage key for the result
            **kwargs: Additional kwargs passed to docket.add()
        rT   Nr   r   r   s          r+   r   z&FunctionResourceTemplate.add_to_docket  sH     ( 'txx
$F5M5ZVZZ
5f5?????r   c                   |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  }i }t        |      D ]5  }|j!                  dd      }||v rt        d	||    d
| d| d      |||<   7 |D ch c]  }|j!                  dd       }}|D ch c]  }|j!                  dd       }}||z  }|st        d      ddlm}m}  ||      }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      | j1                  |      st        d|  d|       t3        d |j                  j                         D              s"|j1                  |      st        d| d|       ||nt	        j4                  |      }|t7        d      }#n(t9        |t:              rt7        j<                  |      }#n|}#|#j?                  ||       t	        j@                  |      s&t9        |tB        jD                        s|jF                  }t9        |tH              r|jJ                  } ||      } ||      }tM        |      }$|$jO                         }%tQ        |%d      }%tS        |      }tU        ||      }& | |||tW        |      nd||||&xs d||%|	xs
 t               |
||#|      S c c}w c c}w c c}w c c}w )z"Create a template from a function.r}   Nz<lambda>z,You must provide a name for lambda functionsz<Functions with *args are not supported as resource templatesz{([\w-]+)(?:\*)?}r3   r4   zURI template parameters 'z' and 'z' both normalize to 'z"'. Use one or the other, not both.z0URI template must contain at least one parameterr   )transform_context_annotationswithout_injected_parametersz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>v  s-      
0 JJ'++7770s   13zURI parameters z- must be a subset of the function arguments: 	forbiddenr   T)prune_titlesrr   )r(   rC   r   r   rq   r   rt   r   rv   r~   r   r   r   ry   ),getattrr|   r}   r
  r   r  rv   valuesr  r  VAR_POSITIONALr'   r"   findallr,   sortedr:   fastmcp.server.dependenciesr  r  keysrs   r  r  issubsetanygetdocr   r   r  	from_boolvalidate_function	isroutine	functoolspartial__call__r   __func__r   json_schemar   r   r   r]   )'r   r   r(   rC   r   r   rq   r   rt   r~   r   r   r   ry   	func_namer  r  raw_path_paramsraw_query_paramsall_rawseenraw_name
normalizedr*   path_paramsquery_paramsall_uri_paramsr  r  
wrapper_fnuser_sigfunc_paramsrequired_paramsoptional_paramsinvalid_query_paramsr   type_adapterrv   resolved_mimes'                                          r+   r   z&FunctionResourceTemplate.from_function  s   & RGB
D9RR\\=R=R	
"KLL #^^**,EzzW..=== R  - bjj)=|LM/= "$44!wH!))#s3JT! /Z0@/A B z!6zl C67 
  (D ( 5DDOqqyyc*OD5EF5E		#s+5EF$|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  &1%<k'..QSBT <$+6Kd#$..t4KK%%b)4   $ZI<M<M-NBb,'B +2.04
-j9!--/
$ZdC
 :& -\9E%$+$7CLT##3|!##
 	
q EF"

s   Q7Q0A0Q#&A0Q(r   r   r   r   r   r   r   r   r   r   )r}   r   r   r   r   r   r   r   r   r   r   r   r   r   rm   r+   r   r     s   8**BF .;?	  )) .);C)	#) )
 NR++ .+;J+	4+>
.%N3 "#@@ @
 @ @ @ 
@2 
  $( "&#' $ $*.&*)-37Z
Z
 Z
 	Z

 "Z
 Z
  Z
 !Z
 Z
 Z
 (Z
 $Z
 'Z
 1Z
 
"Z
 Z
rm   r   )r(   r]   rc   zset[str])r>   r]   rc   zre.Pattern[str] | None)rK   r]   r(   r]   rc   zdict[str, str] | None)r(   r]   rQ   ru   rc   r]   )6r   
__future__r   r*  r   r"   collections.abcr   typingr   r   r   r   urllib.parser	   r
   r   	mcp.typesmcpr   r   pydantic.json_schemar   r   r   docket.executionr   r   r   pydanticr   r   r   fastmcp.resources.baser   r   fastmcp.utilities.authorizationr   fastmcp.utilities.componentsr   fastmcp.utilities.json_schemar   fastmcp.utilities.mimer   fastmcp.utilities.tasksr   r   fastmcp.utilities.typesr   r,   rD   rU   rl   r   r   rm   r+   <module>rQ     s    & "   	 $ 9 9 1 1  ' /* =  < 5 9 9 7 8 :"J$N-`^
' ^
Bf
/ f
rm   