2020
2121logger = logging .getLogger (__name__ )
2222
23+ _DYNAMIC_ROUTE_PATTERN = r"(<\w+>)"
24+ _NAMED_GROUP_BOUNDARY_PATTERN = r"(?P\1\\w+\\b)"
25+
2326
2427class ProxyEventType (Enum ):
2528 """An enumerations of the supported proxy event types."""
@@ -460,8 +463,35 @@ def __call__(self, event, context) -> Any:
460463
461464 @staticmethod
462465 def _compile_regex (rule : str ):
463- """Precompile regex pattern"""
464- rule_regex : str = re .sub (r"(<\w+>)" , r"(?P\1.+)" , rule )
466+ """Precompile regex pattern
467+
468+ Logic
469+ -----
470+
471+ 1. Find any dynamic routes defined as <pattern>
472+ e.g. @app.get("/accounts/<account_id>")
473+ 2. Create a new regex by substituting every dynamic route found as a named group (?P<group>),
474+ and match whole words only (word boundary) instead of a greedy match
475+
476+ non-greedy example with word boundary
477+
478+ rule: '/accounts/<account_id>'
479+ regex: r'/accounts/(?P<account_id>\\ w+\\ b)'
480+
481+ value: /accounts/123/some_other_path
482+ account_id: 123
483+
484+ greedy example without word boundary
485+
486+ regex: r'/accounts/(?P<account_id>.+)'
487+
488+ value: /accounts/123/some_other_path
489+ account_id: 123/some_other_path
490+ 3. Compiles a regex and include start (^) and end ($) in between for an exact match
491+
492+ NOTE: See #520 for context
493+ """
494+ rule_regex : str = re .sub (_DYNAMIC_ROUTE_PATTERN , _NAMED_GROUP_BOUNDARY_PATTERN , rule )
465495 return re .compile ("^{}$" .format (rule_regex ))
466496
467497 def _to_proxy_event (self , event : Dict ) -> BaseProxyEvent :
@@ -485,7 +515,7 @@ def _resolve(self) -> ResponseBuilder:
485515 match : Optional [re .Match ] = route .rule .match (path )
486516 if match :
487517 logger .debug ("Found a registered route. Calling function" )
488- return self ._call_route (route , match .groupdict ())
518+ return self ._call_route (route , match .groupdict ()) # pass fn args
489519
490520 logger .debug (f"No match found for path { path } and method { method } " )
491521 return self ._not_found (method )
0 commit comments