Skip to content

Commit 9d3a3a0

Browse files
committed
fix: move router back to api_gateway.py
1 parent a2c071a commit 9d3a3a0

File tree

7 files changed

+193
-197
lines changed

7 files changed

+193
-197
lines changed

aws_lambda_powertools/event_handler/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
APIGatewayRestResolver,
1010
CORSConfig,
1111
Response,
12+
Router,
1213
)
1314
from .appsync import AppSyncResolver
1415
from .lambda_function_url import LambdaFunctionUrlResolver
@@ -17,7 +18,6 @@
1718
APIGatewayHttpRouter,
1819
APIGatewayRouter,
1920
LambdaFunctionUrlRouter,
20-
Router,
2121
)
2222

2323
__all__ = [

aws_lambda_powertools/event_handler/api_gateway.py

Lines changed: 187 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import traceback
66
import warnings
77
import zlib
8+
from abc import ABC, abstractmethod
89
from enum import Enum
910
from functools import partial
1011
from http import HTTPStatus
@@ -24,7 +25,6 @@
2425

2526
from aws_lambda_powertools.event_handler import content_types
2627
from aws_lambda_powertools.event_handler.exceptions import NotFoundError, ServiceError
27-
from aws_lambda_powertools.event_handler.router import BaseRouter, Router
2828
from aws_lambda_powertools.shared.cookies import Cookie
2929
from aws_lambda_powertools.shared.functions import powertools_dev_is_set
3030
from aws_lambda_powertools.shared.json_encoder import Encoder
@@ -35,6 +35,7 @@
3535
LambdaFunctionUrlEvent,
3636
)
3737
from aws_lambda_powertools.utilities.data_classes.common import BaseProxyEvent
38+
from aws_lambda_powertools.utilities.typing import LambdaContext
3839

3940
logger = logging.getLogger(__name__)
4041

@@ -252,6 +253,165 @@ def build(self, event: BaseProxyEvent, cors: Optional[CORSConfig] = None) -> Dic
252253
}
253254

254255

256+
class BaseRouter(ABC):
257+
current_event: BaseProxyEvent
258+
lambda_context: LambdaContext
259+
context: dict
260+
261+
@abstractmethod
262+
def route(
263+
self,
264+
rule: str,
265+
method: Any,
266+
cors: Optional[bool] = None,
267+
compress: bool = False,
268+
cache_control: Optional[str] = None,
269+
):
270+
raise NotImplementedError()
271+
272+
def get(self, rule: str, cors: Optional[bool] = None, compress: bool = False, cache_control: Optional[str] = None):
273+
"""Get route decorator with GET `method`
274+
275+
Examples
276+
--------
277+
Simple example with a custom lambda handler using the Tracer capture_lambda_handler decorator
278+
279+
```python
280+
from aws_lambda_powertools import Tracer
281+
from aws_lambda_powertools.event_handler import APIGatewayRestResolver
282+
283+
tracer = Tracer()
284+
app = APIGatewayRestResolver()
285+
286+
@app.get("/get-call")
287+
def simple_get():
288+
return {"message": "Foo"}
289+
290+
@tracer.capture_lambda_handler
291+
def lambda_handler(event, context):
292+
return app.resolve(event, context)
293+
```
294+
"""
295+
return self.route(rule, "GET", cors, compress, cache_control)
296+
297+
def post(self, rule: str, cors: Optional[bool] = None, compress: bool = False, cache_control: Optional[str] = None):
298+
"""Post route decorator with POST `method`
299+
300+
Examples
301+
--------
302+
Simple example with a custom lambda handler using the Tracer capture_lambda_handler decorator
303+
304+
```python
305+
from aws_lambda_powertools import Tracer
306+
from aws_lambda_powertools.event_handler import APIGatewayRestResolver
307+
308+
tracer = Tracer()
309+
app = APIGatewayRestResolver()
310+
311+
@app.post("/post-call")
312+
def simple_post():
313+
post_data: dict = app.current_event.json_body
314+
return {"message": post_data["value"]}
315+
316+
@tracer.capture_lambda_handler
317+
def lambda_handler(event, context):
318+
return app.resolve(event, context)
319+
```
320+
"""
321+
return self.route(rule, "POST", cors, compress, cache_control)
322+
323+
def put(self, rule: str, cors: Optional[bool] = None, compress: bool = False, cache_control: Optional[str] = None):
324+
"""Put route decorator with PUT `method`
325+
326+
Examples
327+
--------
328+
Simple example with a custom lambda handler using the Tracer capture_lambda_handler decorator
329+
330+
```python
331+
from aws_lambda_powertools import Tracer
332+
from aws_lambda_powertools.event_handler import APIGatewayRestResolver
333+
334+
tracer = Tracer()
335+
app = APIGatewayRestResolver()
336+
337+
@app.put("/put-call")
338+
def simple_put():
339+
put_data: dict = app.current_event.json_body
340+
return {"message": put_data["value"]}
341+
342+
@tracer.capture_lambda_handler
343+
def lambda_handler(event, context):
344+
return app.resolve(event, context)
345+
```
346+
"""
347+
return self.route(rule, "PUT", cors, compress, cache_control)
348+
349+
def delete(
350+
self, rule: str, cors: Optional[bool] = None, compress: bool = False, cache_control: Optional[str] = None
351+
):
352+
"""Delete route decorator with DELETE `method`
353+
354+
Examples
355+
--------
356+
Simple example with a custom lambda handler using the Tracer capture_lambda_handler decorator
357+
358+
```python
359+
from aws_lambda_powertools import Tracer
360+
from aws_lambda_powertools.event_handler import APIGatewayRestResolver
361+
362+
tracer = Tracer()
363+
app = APIGatewayRestResolver()
364+
365+
@app.delete("/delete-call")
366+
def simple_delete():
367+
return {"message": "deleted"}
368+
369+
@tracer.capture_lambda_handler
370+
def lambda_handler(event, context):
371+
return app.resolve(event, context)
372+
```
373+
"""
374+
return self.route(rule, "DELETE", cors, compress, cache_control)
375+
376+
def patch(
377+
self, rule: str, cors: Optional[bool] = None, compress: bool = False, cache_control: Optional[str] = None
378+
):
379+
"""Patch route decorator with PATCH `method`
380+
381+
Examples
382+
--------
383+
Simple example with a custom lambda handler using the Tracer capture_lambda_handler decorator
384+
385+
```python
386+
from aws_lambda_powertools import Tracer
387+
from aws_lambda_powertools.event_handler import APIGatewayRestResolver
388+
389+
tracer = Tracer()
390+
app = APIGatewayRestResolver()
391+
392+
@app.patch("/patch-call")
393+
def simple_patch():
394+
patch_data: dict = app.current_event.json_body
395+
patch_data["value"] = patched
396+
397+
return {"message": patch_data}
398+
399+
@tracer.capture_lambda_handler
400+
def lambda_handler(event, context):
401+
return app.resolve(event, context)
402+
```
403+
"""
404+
return self.route(rule, "PATCH", cors, compress, cache_control)
405+
406+
def append_context(self, **additional_context):
407+
"""Append key=value data as routing context"""
408+
self.context.update(**additional_context)
409+
410+
def clear_context(self):
411+
"""Resets routing context"""
412+
self.context.clear()
413+
414+
255415
class ApiGatewayResolver(BaseRouter):
256416
"""API Gateway and ALB proxy resolver
257417
@@ -595,7 +755,7 @@ def include_router(self, router: "Router", prefix: Optional[str] = None) -> None
595755
596756
Parameters
597757
----------
598-
router : aws_lambda_powertools.event_handler.router.Router
758+
router : aws_lambda_powertools.event_handler.Router
599759
The Router containing a list of routes to be registered after the existing routes
600760
prefix : str, optional
601761
An optional prefix to be added to the originally defined rule
@@ -618,6 +778,31 @@ def include_router(self, router: "Router", prefix: Optional[str] = None) -> None
618778
self.route(*route)(func)
619779

620780

781+
class Router(BaseRouter):
782+
"""Router helper class to allow splitting ApiGatewayResolver into multiple files"""
783+
784+
def __init__(self):
785+
self._routes: Dict[tuple, Callable] = {}
786+
self.api_resolver: Optional[BaseRouter] = None
787+
self.context = {} # early init as customers might add context before event resolution
788+
789+
def route(
790+
self,
791+
rule: str,
792+
method: Union[str, Union[List[str], Tuple[str]]],
793+
cors: Optional[bool] = None,
794+
compress: bool = False,
795+
cache_control: Optional[str] = None,
796+
):
797+
def register_route(func: Callable):
798+
# Convert methods to tuple. It needs to be hashable as its part of the self._routes dict key
799+
methods = (method,) if isinstance(method, str) else tuple(method)
800+
self._routes[(rule, methods, cors, compress, cache_control)] = func
801+
return func
802+
803+
return register_route
804+
805+
621806
class APIGatewayRestResolver(ApiGatewayResolver):
622807
current_event: APIGatewayProxyEvent
623808

0 commit comments

Comments
 (0)