-
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhandler.py
More file actions
87 lines (68 loc) · 2.86 KB
/
Copy pathhandler.py
File metadata and controls
87 lines (68 loc) · 2.86 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
from aws_lambda_powertools import Logger, Metrics, Tracer
from aws_lambda_powertools.event_handler import APIGatewayRestResolver
from aws_lambda_powertools.event_handler.api_gateway import Response
from aws_lambda_powertools.utilities.typing import LambdaContext
from pydantic import ValidationError
from templates.api.models import Item
from templates.api.response import JsonResponse
from templates.api.settings import Settings
from templates.models import Entity
from templates.repository import Repository
settings = Settings()
logger = Logger(service=settings.service_name)
tracer = Tracer(service=settings.service_name)
metrics = Metrics(namespace=settings.metrics_namespace)
repository = Repository(settings.table_name)
app = APIGatewayRestResolver()
@app.get("/items/<id>")
def get_item(id: str) -> Response:
"""Retrieve an item by ID.
Args:
id: The unique identifier of the item.
Returns:
200 with the item, 400 on invalid ID, 404 if not found, or 500 on error.
"""
try:
Entity(id=id)
except ValidationError:
return JsonResponse({"message": "Invalid item ID"}, status_code=400)
try:
if (item := repository.get_item(id)) is None:
return JsonResponse({"message": f"Item '{id}' not found"}, status_code=404)
item = Item.model_validate(item) # Validate model after retrieval to ensure data integrity
except Exception as exc:
message = "Item validation failed" if isinstance(exc, ValidationError) else "Error retrieving item"
logger.error(message, exc_info=exc, extra={"itemId": id})
return JsonResponse({"message": "Internal server error"}, status_code=500)
return JsonResponse(item.dump_json())
@app.post("/items")
def create_item() -> Response:
"""Create a new item from the request body.
Returns:
201 with the created item, 422 on validation error, or 500 on error.
"""
try:
item = Item.model_validate_json(app.current_event.body)
except ValidationError as exc:
return JsonResponse(
{"message": "Validation failed", "errors": exc.errors(include_input=False, include_url=False)},
status_code=422,
)
try:
repository.put_item(item.dump())
except Exception as exc:
logger.error("DynamoDB put_item failed", exc_info=exc, extra={"itemId": item.id})
return JsonResponse({"message": "Internal server error"}, status_code=500)
return JsonResponse(item.dump_json(), status_code=201)
@logger.inject_lambda_context
@tracer.capture_lambda_handler
@metrics.log_metrics
def main(event: dict, context: LambdaContext) -> dict:
"""Lambda entry point for the API Gateway handler.
Args:
event: The API Gateway proxy event.
context: The Lambda execution context.
Returns:
The API Gateway proxy response.
"""
return app.resolve(event, context)