async-lambda-unstable 0.4.3__tar.gz → 0.4.5__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.
Files changed (33) hide show
  1. {async-lambda-unstable-0.4.3 → async-lambda-unstable-0.4.5}/PKG-INFO +1 -1
  2. {async-lambda-unstable-0.4.3 → async-lambda-unstable-0.4.5}/async_lambda/__init__.py +2 -1
  3. {async-lambda-unstable-0.4.3 → async-lambda-unstable-0.4.5}/async_lambda/config.py +11 -0
  4. {async-lambda-unstable-0.4.3 → async-lambda-unstable-0.4.5}/async_lambda/controller.py +57 -35
  5. {async-lambda-unstable-0.4.3 → async-lambda-unstable-0.4.5}/async_lambda_unstable.egg-info/PKG-INFO +1 -1
  6. {async-lambda-unstable-0.4.3 → async-lambda-unstable-0.4.5}/README.md +0 -0
  7. {async-lambda-unstable-0.4.3 → async-lambda-unstable-0.4.5}/async_lambda/build_config.py +0 -0
  8. {async-lambda-unstable-0.4.3 → async-lambda-unstable-0.4.5}/async_lambda/cli.py +0 -0
  9. {async-lambda-unstable-0.4.3 → async-lambda-unstable-0.4.5}/async_lambda/client.py +0 -0
  10. {async-lambda-unstable-0.4.3 → async-lambda-unstable-0.4.5}/async_lambda/defer.py +0 -0
  11. {async-lambda-unstable-0.4.3 → async-lambda-unstable-0.4.5}/async_lambda/env.py +0 -0
  12. {async-lambda-unstable-0.4.3 → async-lambda-unstable-0.4.5}/async_lambda/middleware.py +0 -0
  13. {async-lambda-unstable-0.4.3 → async-lambda-unstable-0.4.5}/async_lambda/models/__init__.py +0 -0
  14. {async-lambda-unstable-0.4.3 → async-lambda-unstable-0.4.5}/async_lambda/models/case_insensitive_dict.py +0 -0
  15. {async-lambda-unstable-0.4.3 → async-lambda-unstable-0.4.5}/async_lambda/models/events/__init__.py +0 -0
  16. {async-lambda-unstable-0.4.3 → async-lambda-unstable-0.4.5}/async_lambda/models/events/api_event.py +0 -0
  17. {async-lambda-unstable-0.4.3 → async-lambda-unstable-0.4.5}/async_lambda/models/events/base_event.py +0 -0
  18. {async-lambda-unstable-0.4.3 → async-lambda-unstable-0.4.5}/async_lambda/models/events/dynamodb_event.py +0 -0
  19. {async-lambda-unstable-0.4.3 → async-lambda-unstable-0.4.5}/async_lambda/models/events/managed_sqs_event.py +0 -0
  20. {async-lambda-unstable-0.4.3 → async-lambda-unstable-0.4.5}/async_lambda/models/events/scheduled_event.py +0 -0
  21. {async-lambda-unstable-0.4.3 → async-lambda-unstable-0.4.5}/async_lambda/models/events/unmanaged_sqs_event.py +0 -0
  22. {async-lambda-unstable-0.4.3 → async-lambda-unstable-0.4.5}/async_lambda/models/mock/mock_context.py +0 -0
  23. {async-lambda-unstable-0.4.3 → async-lambda-unstable-0.4.5}/async_lambda/models/mock/mock_event.py +0 -0
  24. {async-lambda-unstable-0.4.3 → async-lambda-unstable-0.4.5}/async_lambda/models/task.py +0 -0
  25. {async-lambda-unstable-0.4.3 → async-lambda-unstable-0.4.5}/async_lambda/py.typed +0 -0
  26. {async-lambda-unstable-0.4.3 → async-lambda-unstable-0.4.5}/async_lambda/util.py +0 -0
  27. {async-lambda-unstable-0.4.3 → async-lambda-unstable-0.4.5}/async_lambda_unstable.egg-info/SOURCES.txt +0 -0
  28. {async-lambda-unstable-0.4.3 → async-lambda-unstable-0.4.5}/async_lambda_unstable.egg-info/dependency_links.txt +0 -0
  29. {async-lambda-unstable-0.4.3 → async-lambda-unstable-0.4.5}/async_lambda_unstable.egg-info/entry_points.txt +0 -0
  30. {async-lambda-unstable-0.4.3 → async-lambda-unstable-0.4.5}/async_lambda_unstable.egg-info/requires.txt +0 -0
  31. {async-lambda-unstable-0.4.3 → async-lambda-unstable-0.4.5}/async_lambda_unstable.egg-info/top_level.txt +0 -0
  32. {async-lambda-unstable-0.4.3 → async-lambda-unstable-0.4.5}/pyproject.toml +0 -0
  33. {async-lambda-unstable-0.4.3 → async-lambda-unstable-0.4.5}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: async-lambda-unstable
3
- Version: 0.4.3
3
+ Version: 0.4.5
4
4
  Summary: A framework for creating AWS Lambda Async Workflows. - Unstable Branch
5
5
  Author-email: "Nuclei, Inc" <engineering@nuclei.ai>
6
6
  Description-Content-Type: text/markdown
@@ -1,5 +1,6 @@
1
1
  from .config import config_set_name as config_set_name
2
2
  from .config import config_set_runtime as config_set_runtime
3
+ from .config import config_set_s3_payload_retention as config_set_s3_payload_retention
3
4
  from .controller import AsyncLambdaController as AsyncLambdaController
4
5
  from .defer import Defer as Defer
5
6
  from .env import disable_force_sync_mode as disable_force_sync_mode
@@ -13,4 +14,4 @@ from .models.events.managed_sqs_event import ManagedSQSEvent as ManagedSQSEvent
13
14
  from .models.events.scheduled_event import ScheduledEvent as ScheduledEvent
14
15
  from .models.events.unmanaged_sqs_event import UnmanagedSQSEvent as UnmanagedSQSEvent
15
16
 
16
- __version__ = "0.4.3"
17
+ __version__ = "0.4.5"
@@ -1,6 +1,10 @@
1
+ from typing import Optional
2
+
3
+
1
4
  class AsyncLambdaConfig:
2
5
  name: str = "async-lambda"
3
6
  runtime: str = "python3.10"
7
+ s3_payload_retention: Optional[int] = None
4
8
 
5
9
 
6
10
  config = AsyncLambdaConfig()
@@ -18,3 +22,10 @@ def config_set_runtime(runtime: str):
18
22
  Sets the runtime for the project.
19
23
  """
20
24
  config.runtime = runtime
25
+
26
+
27
+ def config_set_s3_payload_retention(days: int):
28
+ """
29
+ Sets the s3_payload_retention policy in days.
30
+ """
31
+ config.s3_payload_retention = days
@@ -4,12 +4,13 @@ import logging
4
4
  import re
5
5
  import time
6
6
  from datetime import datetime, timezone
7
- from typing import Any, Callable, Dict, List, Optional, Tuple, Type
7
+ from typing import Any, Callable, Dict, List, Optional, Type
8
8
  from uuid import uuid4
9
9
 
10
10
  from . import env
11
11
  from .build_config import get_build_config_for_stage
12
12
  from .client import get_s3_client, get_sqs_client
13
+ from .config import config
13
14
  from .middleware import MET, RT, MiddlewareFunction, MiddlewareRegistration
14
15
  from .models.events.api_event import APIEvent
15
16
  from .models.events.base_event import BaseEvent
@@ -35,6 +36,8 @@ class AsyncLambdaController:
35
36
  current_invocation_id: Optional[str] = None
36
37
  parent_controller: Optional["AsyncLambdaController"] = None
37
38
  middleware: List[MiddlewareRegistration]
39
+ delete_s3_payloads: bool = True
40
+ controller_name: Optional[str] = None
38
41
 
39
42
  dlq_task_id: Optional[str] = None
40
43
 
@@ -44,14 +47,16 @@ class AsyncLambdaController:
44
47
  lane_count: Optional[int] = None,
45
48
  propagate_lane_assignment: Optional[bool] = None,
46
49
  middleware: Optional[List[MiddlewareRegistration]] = None,
47
- exception_handler: Optional[Callable[[Exception], None]] = None,
50
+ delete_s3_payloads: bool = True,
51
+ controller_name: Optional[str] = None,
48
52
  ):
49
53
  self.tasks = dict()
50
54
  self.is_sub = is_sub
51
55
  self.lane_count = lane_count
52
56
  self.propagate_lane_assignment = propagate_lane_assignment
53
57
  self.middleware = middleware or list()
54
- self.exception_handler = exception_handler
58
+ self.delete_s3_payloads = delete_s3_payloads
59
+ self.controller_name = controller_name
55
60
 
56
61
  def add_middleware(
57
62
  self, event_types: List[Type[BaseEvent]], func: MiddlewareFunction[MET, RT]
@@ -136,13 +141,27 @@ class AsyncLambdaController:
136
141
  Generates the SAM Template for this project.
137
142
  """
138
143
  build_config = get_build_config_for_stage(config_dict, stage)
144
+ s3_bucket_properties = {}
145
+ if config.s3_payload_retention:
146
+ s3_bucket_properties["LifecycleConfiguration"] = {
147
+ "Rules": [
148
+ {
149
+ "Id": f"Auto delete objects after {config.s3_payload_retention} days.",
150
+ "ExpirationInDays": config.s3_payload_retention,
151
+ "Status": "Enabled",
152
+ }
153
+ ]
154
+ }
139
155
  template = {
140
156
  "AWSTemplateFormatVersion": "2010-09-09",
141
157
  "Transform": "AWS::Serverless-2016-10-31",
142
158
  "Resources": {
143
159
  "AsyncLambdaPayloadBucket": {
144
160
  "Type": "AWS::S3::Bucket",
145
- "Properties": {"Tags": make_cf_tags(build_config.tags)},
161
+ "Properties": {
162
+ "Tags": make_cf_tags(build_config.tags),
163
+ **s3_bucket_properties,
164
+ },
146
165
  },
147
166
  "AsyncLambdaDLQ": {
148
167
  "Type": "AWS::SQS::Queue",
@@ -273,27 +292,31 @@ class AsyncLambdaController:
273
292
  f"Trigger type of {task.trigger_type} is not supported."
274
293
  )
275
294
  response = task.execute(_event)
276
- if isinstance(_event, ManagedSQSEvent) and _event.s3_payload_key is not None:
295
+ if (
296
+ isinstance(_event, ManagedSQSEvent)
297
+ and _event.s3_payload_key is not None
298
+ and self.delete_s3_payloads
299
+ ):
277
300
  get_s3_client().delete_object(
278
301
  Bucket=env.get_payload_bucket(), Key=_event.s3_payload_key
279
302
  )
280
303
  return response
281
304
 
282
- def _async_invoke(
305
+ def send_async_invoke_payload(
283
306
  self,
284
307
  destination_task_id: str,
285
- payload: Any,
308
+ sqs_payload: dict,
286
309
  delay: Optional[int] = None,
287
310
  force_sync: bool = False,
288
311
  lane: Optional[int] = None,
289
312
  ):
290
313
  """
291
- Invoke an 'async-lambda' task asynchronously utilizing it's SQS queue
314
+ Invoke an 'async-lambda' task asynchronously utilizing it's SQS queue.
292
315
  """
293
316
  if self.parent_controller is not None:
294
- return self.parent_controller._async_invoke(
317
+ return self.parent_controller.send_async_invoke_payload(
295
318
  destination_task_id=destination_task_id,
296
- payload=payload,
319
+ sqs_payload=sqs_payload,
297
320
  delay=delay,
298
321
  force_sync=force_sync,
299
322
  lane=lane,
@@ -319,21 +342,6 @@ class AsyncLambdaController:
319
342
  f"Unable to invoke task {destination_task_id} in lane {lane} because it is not a valid lane for the task."
320
343
  )
321
344
 
322
- if self.current_invocation_id is None:
323
- invocation_id = str(uuid4())
324
- else:
325
- invocation_id = self.current_invocation_id
326
-
327
- sqs_body, payload_size = self._prepare_async_payload(
328
- payload=payload,
329
- invocation_id=invocation_id,
330
- destination_task_id=destination_task.task_id,
331
- force_sync=force_sync or env.get_force_sync_mode(),
332
- )
333
-
334
- logger.info(
335
- f"Invoking task '{destination_task.task_id}' - invocation_id '{invocation_id}' - delay {delay or 0} - size ({payload_size}) - lane {lane}"
336
- )
337
345
  if force_sync or env.get_force_sync_mode():
338
346
  if delay:
339
347
  time.sleep(delay)
@@ -347,27 +355,38 @@ class AsyncLambdaController:
347
355
  and current_task.trigger_type == TaskTriggerType.MANAGED_SQS
348
356
  ):
349
357
  queue_arn = current_task.get_managed_queue_arn(lane=lane)
350
- mock_event = MockSQSLambdaEvent(sqs_body, source_queue_arn=queue_arn)
358
+ mock_event = MockSQSLambdaEvent(
359
+ json.dumps(sqs_payload), source_queue_arn=queue_arn
360
+ )
351
361
  mock_context = MockLambdaContext(destination_task.task_id)
352
- response = self.handle_invocation(
362
+ result = self.handle_invocation(
353
363
  mock_event, mock_context, task_id=destination_task_id
354
364
  )
355
365
  self.set_current_task_id(current_task_id)
356
- return response
366
+ return result
357
367
  else:
358
368
  get_sqs_client().send_message(
359
369
  QueueUrl=destination_task.get_managed_queue_url(lane=lane),
360
- MessageBody=sqs_body,
370
+ MessageBody=json.dumps(sqs_payload),
361
371
  DelaySeconds=delay,
362
372
  )
363
373
 
364
- def _prepare_async_payload(
374
+ def new_payload(
365
375
  self,
366
376
  payload: Any,
367
- invocation_id: str,
368
377
  destination_task_id: str,
369
378
  force_sync: bool,
370
- ) -> Tuple[str, int]:
379
+ ) -> dict:
380
+ if self.parent_controller is not None:
381
+ return self.parent_controller.new_payload(
382
+ payload=payload,
383
+ destination_task_id=destination_task_id,
384
+ force_sync=force_sync,
385
+ )
386
+ if self.current_invocation_id is None:
387
+ invocation_id = str(uuid4())
388
+ else:
389
+ invocation_id = self.current_invocation_id
371
390
  raw_sqs_body = {
372
391
  "source_task_id": self.current_task_id,
373
392
  "destination_task_id": destination_task_id,
@@ -391,7 +410,7 @@ class AsyncLambdaController:
391
410
  else:
392
411
  raw_sqs_body["payload"] = serialized_payload
393
412
 
394
- return json.dumps(raw_sqs_body), payload_size
413
+ return raw_sqs_body
395
414
 
396
415
  def add_controller(self, controller: "AsyncLambdaController"):
397
416
  controller.parent_controller = self
@@ -409,9 +428,12 @@ class AsyncLambdaController:
409
428
  """
410
429
  Invoke an Async-Lambda task.
411
430
  """
412
- return self._async_invoke(
431
+ sqs_payload = self.new_payload(
432
+ payload=payload, destination_task_id=task_id, force_sync=force_sync
433
+ )
434
+ return self.send_async_invoke_payload(
413
435
  destination_task_id=task_id,
414
- payload=payload,
436
+ sqs_payload=sqs_payload,
415
437
  delay=delay,
416
438
  force_sync=force_sync,
417
439
  lane=lane,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: async-lambda-unstable
3
- Version: 0.4.3
3
+ Version: 0.4.5
4
4
  Summary: A framework for creating AWS Lambda Async Workflows. - Unstable Branch
5
5
  Author-email: "Nuclei, Inc" <engineering@nuclei.ai>
6
6
  Description-Content-Type: text/markdown