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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: turbo-lambda
3
- Version: 0.6.2
3
+ Version: 0.7.1
4
4
  Summary: Turbo Lambda Description
5
5
  Author: Sam Mosleh
6
6
  Author-email: Sam Mosleh <sam.mosleh.d@gmail.com>
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "turbo-lambda"
3
- version = "0.6.2"
3
+ version = "0.7.1"
4
4
  description = "Turbo Lambda Description"
5
5
  readme = "README.md"
6
6
  authors = [{ name = "Sam Mosleh", email = "sam.mosleh.d@gmail.com" }]
@@ -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[schemas.OnErrorNone[RequestT]],
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(single_record_processor, event.records)
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", "context"),
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", "context"),
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", "context"),
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