turbo-lambda 0.6.2__tar.gz → 0.7.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {turbo_lambda-0.6.2 → turbo_lambda-0.7.1}/PKG-INFO +1 -1
- {turbo_lambda-0.6.2 → turbo_lambda-0.7.1}/pyproject.toml +1 -1
- {turbo_lambda-0.6.2 → turbo_lambda-0.7.1}/src/turbo_lambda/decorators.py +21 -12
- {turbo_lambda-0.6.2 → turbo_lambda-0.7.1}/src/turbo_lambda/log.py +7 -3
- {turbo_lambda-0.6.2 → turbo_lambda-0.7.1}/src/turbo_lambda/schemas.py +9 -0
- {turbo_lambda-0.6.2 → turbo_lambda-0.7.1}/README.md +0 -0
- {turbo_lambda-0.6.2 → turbo_lambda-0.7.1}/src/turbo_lambda/__init__.py +0 -0
- {turbo_lambda-0.6.2 → turbo_lambda-0.7.1}/src/turbo_lambda/errors.py +0 -0
- {turbo_lambda-0.6.2 → turbo_lambda-0.7.1}/src/turbo_lambda/py.typed +0 -0
- {turbo_lambda-0.6.2 → turbo_lambda-0.7.1}/src/turbo_lambda/scripts/__init__.py +0 -0
- {turbo_lambda-0.6.2 → turbo_lambda-0.7.1}/src/turbo_lambda/scripts/update_turbo_lambda_layer.py +0 -0
- {turbo_lambda-0.6.2 → turbo_lambda-0.7.1}/src/turbo_lambda/version.py +0 -0
|
@@ -2,7 +2,8 @@ import inspect
|
|
|
2
2
|
import logging
|
|
3
3
|
from collections.abc import Callable
|
|
4
4
|
from concurrent.futures import ThreadPoolExecutor
|
|
5
|
-
from contextlib import AbstractContextManager
|
|
5
|
+
from contextlib import AbstractContextManager, ContextDecorator
|
|
6
|
+
from contextlib import suppress as contextlib_suppress
|
|
6
7
|
from functools import wraps
|
|
7
8
|
from types import TracebackType
|
|
8
9
|
from typing import Any, Protocol, overload
|
|
@@ -12,7 +13,6 @@ from opentelemetry.trace import format_span_id, format_trace_id, get_current_spa
|
|
|
12
13
|
|
|
13
14
|
from turbo_lambda import schemas
|
|
14
15
|
from turbo_lambda.errors import (
|
|
15
|
-
GeneralError,
|
|
16
16
|
RequestValidationError,
|
|
17
17
|
general_error_to_gateway_response,
|
|
18
18
|
)
|
|
@@ -126,6 +126,7 @@ def request_logger_handler[ResponseT](
|
|
|
126
126
|
log_level=logging.DEBUG,
|
|
127
127
|
log_message="request",
|
|
128
128
|
log_exceptions=True,
|
|
129
|
+
excluded_fields=("context",),
|
|
129
130
|
)
|
|
130
131
|
@wraps(func)
|
|
131
132
|
def handler(
|
|
@@ -166,6 +167,7 @@ def gateway_handler[RequestT: pydantic.BaseModel](
|
|
|
166
167
|
log_level=logging.DEBUG,
|
|
167
168
|
log_message="request",
|
|
168
169
|
log_exceptions=True,
|
|
170
|
+
excluded_fields=("context",),
|
|
169
171
|
result_extractor=result_extractor,
|
|
170
172
|
)
|
|
171
173
|
@error_transformer_handler(general_error_to_gateway_response)
|
|
@@ -199,18 +201,10 @@ def parallel_sqs_handler[RequestT](
|
|
|
199
201
|
).annotation
|
|
200
202
|
|
|
201
203
|
def single_record_processor(
|
|
202
|
-
rec: schemas.SqsRecordModel[
|
|
204
|
+
rec: schemas.SqsRecordModel[RequestT],
|
|
203
205
|
) -> schemas.LambdaCheckpointItem | None:
|
|
204
|
-
if rec.body is None:
|
|
205
|
-
logger.warning(
|
|
206
|
-
"sqs_message_ignored",
|
|
207
|
-
extra={"message_id": rec.message_id},
|
|
208
|
-
)
|
|
209
|
-
return None
|
|
210
206
|
try:
|
|
211
207
|
func(rec.body)
|
|
212
|
-
except GeneralError:
|
|
213
|
-
pass
|
|
214
208
|
except Exception:
|
|
215
209
|
return schemas.LambdaCheckpointItem(item_identifier=rec.message_id)
|
|
216
210
|
return None
|
|
@@ -218,8 +212,19 @@ def parallel_sqs_handler[RequestT](
|
|
|
218
212
|
def wrapper(
|
|
219
213
|
event: schemas.SqsEvent[schemas.OnErrorNone[request_type]], # type: ignore[valid-type]
|
|
220
214
|
) -> schemas.LambdaCheckpointResponse:
|
|
215
|
+
ignored_messages = [
|
|
216
|
+
rec.message_id for rec in event.records if rec.body is None
|
|
217
|
+
]
|
|
218
|
+
if ignored_messages:
|
|
219
|
+
logger.warning(
|
|
220
|
+
"sqs_message_ignored",
|
|
221
|
+
extra={"message_ids": ignored_messages},
|
|
222
|
+
)
|
|
221
223
|
with ThreadPoolExecutor(max_workers=max_workers) as executor:
|
|
222
|
-
responses = executor.map(
|
|
224
|
+
responses = executor.map(
|
|
225
|
+
single_record_processor,
|
|
226
|
+
[rec for rec in event.records if rec.body is not None],
|
|
227
|
+
)
|
|
223
228
|
return schemas.LambdaCheckpointResponse(
|
|
224
229
|
batch_item_failures=[item for item in responses if item is not None]
|
|
225
230
|
)
|
|
@@ -247,3 +252,7 @@ class CachedContextManager[T]:
|
|
|
247
252
|
|
|
248
253
|
def __call__(self) -> T:
|
|
249
254
|
return self._value
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
class suppress(contextlib_suppress, ContextDecorator): # noqa: N801
|
|
258
|
+
pass
|
|
@@ -4,7 +4,9 @@ import datetime
|
|
|
4
4
|
import inspect
|
|
5
5
|
import logging
|
|
6
6
|
import time
|
|
7
|
+
import uuid
|
|
7
8
|
from collections.abc import Callable, Generator, Iterable
|
|
9
|
+
from enum import Enum
|
|
8
10
|
from functools import wraps
|
|
9
11
|
from typing import Any, overload
|
|
10
12
|
|
|
@@ -38,6 +40,8 @@ def _json_custom_default(value: Any) -> Any:
|
|
|
38
40
|
return value.model_dump(mode="json")
|
|
39
41
|
case datetime.datetime() | datetime.date():
|
|
40
42
|
return value.isoformat()
|
|
43
|
+
case uuid.UUID() | Enum():
|
|
44
|
+
return str(value)
|
|
41
45
|
case set():
|
|
42
46
|
return list(value)
|
|
43
47
|
case _:
|
|
@@ -63,7 +67,7 @@ def log_after_call[**P, T](
|
|
|
63
67
|
log_level: int = logging.INFO,
|
|
64
68
|
log_message: str = "call",
|
|
65
69
|
log_exceptions: bool = False,
|
|
66
|
-
excluded_fields: Iterable[str] = ("self",
|
|
70
|
+
excluded_fields: Iterable[str] = ("self",),
|
|
67
71
|
result_extractor: None = None,
|
|
68
72
|
) -> Callable[[Callable[P, T]], Callable[P, T]]: ...
|
|
69
73
|
|
|
@@ -74,7 +78,7 @@ def log_after_call[**P, T](
|
|
|
74
78
|
log_level: int = logging.INFO,
|
|
75
79
|
log_message: str = "call",
|
|
76
80
|
log_exceptions: bool = False,
|
|
77
|
-
excluded_fields: Iterable[str] = ("self",
|
|
81
|
+
excluded_fields: Iterable[str] = ("self",),
|
|
78
82
|
result_extractor: Callable[[T], dict[str, Any]],
|
|
79
83
|
) -> Callable[[Callable[P, T]], Callable[P, T]]: ...
|
|
80
84
|
|
|
@@ -84,7 +88,7 @@ def log_after_call[**P, T]( # noqa: PLR0913
|
|
|
84
88
|
log_level: int = logging.INFO,
|
|
85
89
|
log_message: str = "call",
|
|
86
90
|
log_exceptions: bool = False,
|
|
87
|
-
excluded_fields: Iterable[str] = ("self",
|
|
91
|
+
excluded_fields: Iterable[str] = ("self",),
|
|
88
92
|
result_extractor: Callable[[T], dict[str, Any]] | None = None,
|
|
89
93
|
) -> Callable[P, T] | Callable[[Callable[P, T]], Callable[P, T]]:
|
|
90
94
|
def decorator(func: Callable[P, T]) -> Callable[P, T]:
|
|
@@ -46,6 +46,10 @@ class LambdaContextProtocol(Protocol):
|
|
|
46
46
|
aws_request_id: str
|
|
47
47
|
|
|
48
48
|
|
|
49
|
+
class GatewayEventHeaders[HeaderT](pydantic.BaseModel):
|
|
50
|
+
headers: HeaderT
|
|
51
|
+
|
|
52
|
+
|
|
49
53
|
class GatewayEventPathParameters[ParamT](pydantic.BaseModel):
|
|
50
54
|
path_parameters: Annotated[ParamT, pydantic.Field(alias="pathParameters")]
|
|
51
55
|
|
|
@@ -541,3 +545,8 @@ class AuthorizerResponse(pydantic.BaseModel):
|
|
|
541
545
|
AuthorizerPolicyDocument, pydantic.Field(serialization_alias="policyDocument")
|
|
542
546
|
]
|
|
543
547
|
context: dict[str, str]
|
|
548
|
+
|
|
549
|
+
|
|
550
|
+
class AuthorizerResponseV2(pydantic.BaseModel):
|
|
551
|
+
is_authorized: Annotated[bool, pydantic.Field(alias="isAuthorized")]
|
|
552
|
+
context: dict[str, str] = {}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{turbo_lambda-0.6.2 → turbo_lambda-0.7.1}/src/turbo_lambda/scripts/update_turbo_lambda_layer.py
RENAMED
|
File without changes
|
|
File without changes
|