@@ -37,7 +37,7 @@ class ProxyEventType(Enum):
3737 ALBEvent = "ALBEvent"
3838
3939
40- class CORSConfig ( object ) :
40+ class CORSConfig :
4141 """CORS Config
4242
4343 Examples
@@ -265,6 +265,7 @@ def __init__(
265265 cors : Optional [CORSConfig ] = None ,
266266 debug : Optional [bool ] = None ,
267267 serializer : Optional [Callable [[Dict ], str ]] = None ,
268+ strip_prefixes : Optional [List [str ]] = None ,
268269 ):
269270 """
270271 Parameters
@@ -276,6 +277,11 @@ def __init__(
276277 debug: Optional[bool]
277278 Enables debug mode, by default False. Can be also be enabled by "POWERTOOLS_EVENT_HANDLER_DEBUG"
278279 environment variable
280+ serializer : Callable, optional
281+ function to serialize `obj` to a JSON formatted `str`, by default json.dumps
282+ strip_prefixes: List[str], optional
283+ optional list of prefixes to be removed from the request path before doing the routing. This is often used
284+ with api gateways with multiple custom mappings.
279285 """
280286 self ._proxy_type = proxy_type
281287 self ._routes : List [Route ] = []
@@ -285,6 +291,7 @@ def __init__(
285291 self ._debug = resolve_truthy_env_var_choice (
286292 env = os .getenv (constants .EVENT_HANDLER_DEBUG_ENV , "false" ), choice = debug
287293 )
294+ self ._strip_prefixes = strip_prefixes
288295
289296 # Allow for a custom serializer or a concise json serialization
290297 self ._serializer = serializer or partial (json .dumps , separators = ("," , ":" ), cls = Encoder )
@@ -521,7 +528,7 @@ def _to_proxy_event(self, event: Dict) -> BaseProxyEvent:
521528 def _resolve (self ) -> ResponseBuilder :
522529 """Resolves the response or return the not found response"""
523530 method = self .current_event .http_method .upper ()
524- path = self .current_event .path
531+ path = self ._remove_prefix ( self . current_event .path )
525532 for route in self ._routes :
526533 if method != route .method :
527534 continue
@@ -533,6 +540,25 @@ def _resolve(self) -> ResponseBuilder:
533540 logger .debug (f"No match found for path { path } and method { method } " )
534541 return self ._not_found (method )
535542
543+ def _remove_prefix (self , path : str ) -> str :
544+ """Remove the configured prefix from the path"""
545+ if not isinstance (self ._strip_prefixes , list ):
546+ return path
547+
548+ for prefix in self ._strip_prefixes :
549+ if self ._path_starts_with (path , prefix ):
550+ return path [len (prefix ) :]
551+
552+ return path
553+
554+ @staticmethod
555+ def _path_starts_with (path : str , prefix : str ):
556+ """Returns true if the `path` starts with a prefix plus a `/`"""
557+ if not isinstance (prefix , str ) or len (prefix ) == 0 :
558+ return False
559+
560+ return path .startswith (prefix + "/" )
561+
536562 def _not_found (self , method : str ) -> ResponseBuilder :
537563 """Called when no matching route was found and includes support for the cors preflight response"""
538564 headers = {}
0 commit comments