@@ -33,6 +33,8 @@ class ResourceTemplate(BaseModel):
3333 fn : Callable [..., Any ] = Field (exclude = True )
3434 parameters : dict [str , Any ] = Field (description = "JSON schema for function parameters" )
3535 context_kwarg : str | None = Field (None , description = "Name of the kwarg that should receive context" )
36+ _compiled_pattern : re .Pattern [str ] | None = None
37+ _convertors : dict [str , Convertor [Any ]] | None = None
3638
3739 @classmethod
3840 def from_function (
@@ -77,12 +79,9 @@ def from_function(
7779 context_kwarg = context_kwarg ,
7880 )
7981
80- def matches (self , uri : str ) -> dict [str , Any ] | None :
81- """Check if URI matches template and extract parameters."""
82- uriTemplate = str (self .uri_template )
83- uri = str (uri )
84-
85- parts = uriTemplate .strip ("/" ).split ("/" )
82+ def _generate_pattern (self ) -> tuple [re .Pattern [str ], dict [str , Convertor [Any ]]]:
83+ """Compile the URI template into a regex pattern and associated converters."""
84+ parts = self .uri_template .strip ("/" ).split ("/" )
8685 pattern_parts : list [str ] = []
8786 converters : dict [str , Convertor [Any ]] = {}
8887 # generate the regex pattern
@@ -106,21 +105,26 @@ def matches(self, uri: str) -> dict[str, Any] | None:
106105 else :
107106 pattern_parts .append (re .escape (part ))
108107
109- pattern = "^" + "/" .join (pattern_parts ) + "$"
110- # check if the pattern matches
111- regex = re .compile (pattern )
112- match = regex .match (uri .strip ("/" ))
108+ return re .compile ("^" + "/" .join (pattern_parts ) + "$" ),converters
109+
110+ def matches (self , uri : str ) -> dict [str , Any ] | None :
111+ """Check if URI matches template and extract parameters."""
112+ if not self ._compiled_pattern or not self ._convertors :
113+ self ._compiled_pattern ,self ._convertors = self ._generate_pattern ()
114+
115+ uri = str (uri )
116+ match = self ._compiled_pattern .match (uri .strip ("/" ))
113117 if not match :
114118 return None
115119
116120 # try to convert them into respective types
117121 result : dict [str , Any ] = {}
118- for name , conv in converters .items ():
122+ for name , conv in self . _convertors .items ():
119123 raw_value = match .group (name )
120124 try :
121125 result [name ] = conv .convert (raw_value )
122- except Exception :
123- return None
126+ except Exception as e :
127+ raise ValueError ( f"Failed to convert ' { raw_value } ' for ' { name } ': { e } " )
124128
125129 return result
126130
0 commit comments