async-lambda-unstable 0.4.18__tar.gz → 0.5.2__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.
- {async-lambda-unstable-0.4.18 → async-lambda-unstable-0.5.2}/PKG-INFO +1 -1
- {async-lambda-unstable-0.4.18 → async-lambda-unstable-0.5.2}/async_lambda/__init__.py +1 -1
- {async-lambda-unstable-0.4.18 → async-lambda-unstable-0.5.2}/async_lambda/client.py +8 -0
- {async-lambda-unstable-0.4.18 → async-lambda-unstable-0.5.2}/async_lambda/controller.py +136 -44
- async-lambda-unstable-0.5.2/async_lambda/env.py +81 -0
- {async-lambda-unstable-0.4.18 → async-lambda-unstable-0.5.2}/async_lambda/models/task.py +28 -1
- {async-lambda-unstable-0.4.18 → async-lambda-unstable-0.5.2}/async_lambda_unstable.egg-info/PKG-INFO +1 -1
- async-lambda-unstable-0.4.18/async_lambda/env.py +0 -37
- {async-lambda-unstable-0.4.18 → async-lambda-unstable-0.5.2}/README.md +0 -0
- {async-lambda-unstable-0.4.18 → async-lambda-unstable-0.5.2}/async_lambda/build_config.py +0 -0
- {async-lambda-unstable-0.4.18 → async-lambda-unstable-0.5.2}/async_lambda/cli.py +0 -0
- {async-lambda-unstable-0.4.18 → async-lambda-unstable-0.5.2}/async_lambda/config.py +0 -0
- {async-lambda-unstable-0.4.18 → async-lambda-unstable-0.5.2}/async_lambda/defer.py +0 -0
- {async-lambda-unstable-0.4.18 → async-lambda-unstable-0.5.2}/async_lambda/middleware.py +0 -0
- {async-lambda-unstable-0.4.18 → async-lambda-unstable-0.5.2}/async_lambda/models/__init__.py +0 -0
- {async-lambda-unstable-0.4.18 → async-lambda-unstable-0.5.2}/async_lambda/models/api_response.py +0 -0
- {async-lambda-unstable-0.4.18 → async-lambda-unstable-0.5.2}/async_lambda/models/case_insensitive_dict.py +0 -0
- {async-lambda-unstable-0.4.18 → async-lambda-unstable-0.5.2}/async_lambda/models/events/__init__.py +0 -0
- {async-lambda-unstable-0.4.18 → async-lambda-unstable-0.5.2}/async_lambda/models/events/api_event.py +0 -0
- {async-lambda-unstable-0.4.18 → async-lambda-unstable-0.5.2}/async_lambda/models/events/base_event.py +0 -0
- {async-lambda-unstable-0.4.18 → async-lambda-unstable-0.5.2}/async_lambda/models/events/dynamodb_event.py +0 -0
- {async-lambda-unstable-0.4.18 → async-lambda-unstable-0.5.2}/async_lambda/models/events/managed_sqs_batch_event.py +0 -0
- {async-lambda-unstable-0.4.18 → async-lambda-unstable-0.5.2}/async_lambda/models/events/managed_sqs_event.py +0 -0
- {async-lambda-unstable-0.4.18 → async-lambda-unstable-0.5.2}/async_lambda/models/events/scheduled_event.py +0 -0
- {async-lambda-unstable-0.4.18 → async-lambda-unstable-0.5.2}/async_lambda/models/events/unmanaged_sqs_event.py +0 -0
- {async-lambda-unstable-0.4.18 → async-lambda-unstable-0.5.2}/async_lambda/models/mock/mock_context.py +0 -0
- {async-lambda-unstable-0.4.18 → async-lambda-unstable-0.5.2}/async_lambda/models/mock/mock_event.py +0 -0
- {async-lambda-unstable-0.4.18 → async-lambda-unstable-0.5.2}/async_lambda/payload_encoder.py +0 -0
- {async-lambda-unstable-0.4.18 → async-lambda-unstable-0.5.2}/async_lambda/py.typed +0 -0
- {async-lambda-unstable-0.4.18 → async-lambda-unstable-0.5.2}/async_lambda/util.py +0 -0
- {async-lambda-unstable-0.4.18 → async-lambda-unstable-0.5.2}/async_lambda_unstable.egg-info/SOURCES.txt +0 -0
- {async-lambda-unstable-0.4.18 → async-lambda-unstable-0.5.2}/async_lambda_unstable.egg-info/dependency_links.txt +0 -0
- {async-lambda-unstable-0.4.18 → async-lambda-unstable-0.5.2}/async_lambda_unstable.egg-info/entry_points.txt +0 -0
- {async-lambda-unstable-0.4.18 → async-lambda-unstable-0.5.2}/async_lambda_unstable.egg-info/requires.txt +0 -0
- {async-lambda-unstable-0.4.18 → async-lambda-unstable-0.5.2}/async_lambda_unstable.egg-info/top_level.txt +0 -0
- {async-lambda-unstable-0.4.18 → async-lambda-unstable-0.5.2}/pyproject.toml +0 -0
- {async-lambda-unstable-0.4.18 → async-lambda-unstable-0.5.2}/setup.cfg +0 -0
|
@@ -19,4 +19,4 @@ from .models.events.managed_sqs_event import ManagedSQSEvent as ManagedSQSEvent
|
|
|
19
19
|
from .models.events.scheduled_event import ScheduledEvent as ScheduledEvent
|
|
20
20
|
from .models.events.unmanaged_sqs_event import UnmanagedSQSEvent as UnmanagedSQSEvent
|
|
21
21
|
|
|
22
|
-
__version__ = "0.
|
|
22
|
+
__version__ = "0.5.2"
|
|
@@ -7,10 +7,12 @@ import boto3
|
|
|
7
7
|
class Clients:
|
|
8
8
|
s3_client: Optional[Any] = None
|
|
9
9
|
sqs_client: Optional[Any] = None
|
|
10
|
+
sts_client: Optional[Any] = None
|
|
10
11
|
|
|
11
12
|
def reset(self):
|
|
12
13
|
self.s3_client = None
|
|
13
14
|
self.sqs_client = None
|
|
15
|
+
self.sts_client = None
|
|
14
16
|
|
|
15
17
|
|
|
16
18
|
clients = Clients()
|
|
@@ -33,3 +35,9 @@ def get_sqs_client():
|
|
|
33
35
|
if clients.sqs_client is None:
|
|
34
36
|
clients.sqs_client = boto3.client("sqs", **get_client_kwargs())
|
|
35
37
|
return clients.sqs_client
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def get_sts_client():
|
|
41
|
+
if clients.sts_client is None:
|
|
42
|
+
clients.sts_client = boto3.client("sts", **get_client_kwargs())
|
|
43
|
+
return clients.sts_client
|
|
@@ -4,7 +4,18 @@ import logging
|
|
|
4
4
|
import re
|
|
5
5
|
import time
|
|
6
6
|
from datetime import datetime, timezone
|
|
7
|
-
from typing import
|
|
7
|
+
from typing import (
|
|
8
|
+
Any,
|
|
9
|
+
Callable,
|
|
10
|
+
Dict,
|
|
11
|
+
List,
|
|
12
|
+
Optional,
|
|
13
|
+
Sequence,
|
|
14
|
+
Set,
|
|
15
|
+
Type,
|
|
16
|
+
TypeVar,
|
|
17
|
+
Union,
|
|
18
|
+
)
|
|
8
19
|
from uuid import uuid4
|
|
9
20
|
|
|
10
21
|
from . import env
|
|
@@ -41,6 +52,7 @@ class AsyncLambdaController:
|
|
|
41
52
|
lane_count: Optional[int] = None
|
|
42
53
|
propagate_lane_assignment: Optional[bool] = None
|
|
43
54
|
tasks: Dict[str, AsyncLambdaTask]
|
|
55
|
+
external_async_tasks: Set[str]
|
|
44
56
|
current_task_id: Optional[str] = None
|
|
45
57
|
current_lane: Optional[int] = None
|
|
46
58
|
current_invocation_id: Optional[str] = None
|
|
@@ -61,6 +73,7 @@ class AsyncLambdaController:
|
|
|
61
73
|
controller_name: Optional[str] = None,
|
|
62
74
|
):
|
|
63
75
|
self.tasks = dict()
|
|
76
|
+
self.external_async_tasks = set()
|
|
64
77
|
self.is_sub = is_sub
|
|
65
78
|
self.lane_count = lane_count
|
|
66
79
|
self.propagate_lane_assignment = propagate_lane_assignment
|
|
@@ -97,6 +110,16 @@ class AsyncLambdaController:
|
|
|
97
110
|
)
|
|
98
111
|
self.tasks[task.task_id] = task
|
|
99
112
|
|
|
113
|
+
def add_external_task(self, external_task_id: str):
|
|
114
|
+
"""
|
|
115
|
+
Adds an external task to the controller, which will then be enabled to async_invoke.
|
|
116
|
+
|
|
117
|
+
`external_task_id` is `{config.name}-{task_id}` of the external task (the queue name)
|
|
118
|
+
|
|
119
|
+
Sending payloads via S3 is not currently supported with external tasks.
|
|
120
|
+
"""
|
|
121
|
+
self.external_async_tasks.add(external_task_id)
|
|
122
|
+
|
|
100
123
|
def get_lane_count(self) -> int:
|
|
101
124
|
if self.lane_count is not None:
|
|
102
125
|
return self.lane_count
|
|
@@ -193,7 +216,11 @@ class AsyncLambdaController:
|
|
|
193
216
|
if task.trigger_type == TaskTriggerType.API_EVENT:
|
|
194
217
|
has_api_tasks = True
|
|
195
218
|
for logical_id, resource in task.get_sam_template(
|
|
196
|
-
module,
|
|
219
|
+
module=module,
|
|
220
|
+
tasks=_task_list,
|
|
221
|
+
external_async_tasks=self.external_async_tasks,
|
|
222
|
+
config_dict=config_dict,
|
|
223
|
+
stage=stage,
|
|
197
224
|
).items():
|
|
198
225
|
template["Resources"][logical_id] = resource
|
|
199
226
|
|
|
@@ -354,28 +381,44 @@ class AsyncLambdaController:
|
|
|
354
381
|
force_sync=force_sync,
|
|
355
382
|
lane=lane,
|
|
356
383
|
)
|
|
384
|
+
is_external_task = False
|
|
357
385
|
if destination_task_id not in self.tasks:
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
386
|
+
if destination_task_id in self.external_async_tasks:
|
|
387
|
+
is_external_task = True
|
|
388
|
+
else:
|
|
389
|
+
raise Exception(
|
|
390
|
+
f"No such task exists with the task_id {destination_task_id}"
|
|
391
|
+
)
|
|
392
|
+
if not is_external_task:
|
|
393
|
+
destination_task = self.tasks[destination_task_id]
|
|
394
|
+
if destination_task.trigger_type not in MANAGED_SQS_TASK_TYPES:
|
|
395
|
+
raise Exception(
|
|
396
|
+
f"Unable to invoke task '{destination_task_id}' because it is a {destination_task.trigger_type} task"
|
|
397
|
+
)
|
|
361
398
|
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
)
|
|
399
|
+
if lane is None and destination_task.should_propagate_lane_assignment():
|
|
400
|
+
lane = self.get_current_lane()
|
|
401
|
+
if lane is None:
|
|
402
|
+
lane = 0
|
|
367
403
|
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
404
|
+
if lane < 0 or lane >= destination_task.get_lane_count():
|
|
405
|
+
raise Exception(
|
|
406
|
+
f"Unable to invoke task {destination_task_id} in lane {lane} because it is not a valid lane for the task."
|
|
407
|
+
)
|
|
408
|
+
else:
|
|
409
|
+
if lane is None:
|
|
410
|
+
lane = self.get_current_lane()
|
|
411
|
+
if lane != 0:
|
|
412
|
+
logger.warning(
|
|
413
|
+
f"Selected lane is {lane}. External tasks only support lane 0."
|
|
414
|
+
)
|
|
371
415
|
lane = 0
|
|
372
416
|
|
|
373
|
-
if lane < 0 or lane >= destination_task.get_lane_count():
|
|
374
|
-
raise Exception(
|
|
375
|
-
f"Unable to invoke task {destination_task_id} in lane {lane} because it is not a valid lane for the task."
|
|
376
|
-
)
|
|
377
|
-
|
|
378
417
|
if force_sync or env.get_force_sync_mode():
|
|
418
|
+
if is_external_task:
|
|
419
|
+
raise NotImplementedError(
|
|
420
|
+
f"Unable to run external task {destination_task_id} locally."
|
|
421
|
+
)
|
|
379
422
|
if delay:
|
|
380
423
|
time.sleep(delay)
|
|
381
424
|
# Sync invocation with mock event/context
|
|
@@ -393,8 +436,12 @@ class AsyncLambdaController:
|
|
|
393
436
|
self.set_current_lane(current_lane)
|
|
394
437
|
return result
|
|
395
438
|
else:
|
|
439
|
+
if is_external_task:
|
|
440
|
+
url = f"https://sqs.{env.get_aws_region()}.amazonaws.com/{env.get_aws_account_id()}/{destination_task_id}"
|
|
441
|
+
else:
|
|
442
|
+
url = destination_task.get_managed_queue_url(lane=lane)
|
|
396
443
|
get_sqs_client().send_message(
|
|
397
|
-
QueueUrl=
|
|
444
|
+
QueueUrl=url,
|
|
398
445
|
MessageBody=json.dumps(sqs_payload),
|
|
399
446
|
DelaySeconds=delay,
|
|
400
447
|
)
|
|
@@ -419,29 +466,45 @@ class AsyncLambdaController:
|
|
|
419
466
|
force_sync=force_sync,
|
|
420
467
|
lane=lane,
|
|
421
468
|
)
|
|
469
|
+
|
|
470
|
+
is_external_task = False
|
|
422
471
|
if destination_task_id not in self.tasks:
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
472
|
+
if destination_task_id in self.external_async_tasks:
|
|
473
|
+
is_external_task = True
|
|
474
|
+
else:
|
|
475
|
+
raise Exception(
|
|
476
|
+
f"No such task exists with the task_id {destination_task_id}"
|
|
477
|
+
)
|
|
478
|
+
if not is_external_task:
|
|
479
|
+
destination_task = self.tasks[destination_task_id]
|
|
480
|
+
if destination_task.trigger_type not in MANAGED_SQS_TASK_TYPES:
|
|
481
|
+
raise Exception(
|
|
482
|
+
f"Unable to invoke task '{destination_task_id}' because it is a {destination_task.trigger_type} task"
|
|
483
|
+
)
|
|
426
484
|
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
)
|
|
485
|
+
if lane is None and destination_task.should_propagate_lane_assignment():
|
|
486
|
+
lane = self.get_current_lane()
|
|
487
|
+
if lane is None:
|
|
488
|
+
lane = 0
|
|
432
489
|
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
490
|
+
if lane < 0 or lane >= destination_task.get_lane_count():
|
|
491
|
+
raise Exception(
|
|
492
|
+
f"Unable to invoke task {destination_task_id} in lane {lane} because it is not a valid lane for the task."
|
|
493
|
+
)
|
|
494
|
+
else:
|
|
495
|
+
if lane is None:
|
|
496
|
+
lane = self.get_current_lane()
|
|
497
|
+
if lane != 0:
|
|
498
|
+
logger.warning(
|
|
499
|
+
f"Selected lane is {lane}. External tasks only support lane 0."
|
|
500
|
+
)
|
|
436
501
|
lane = 0
|
|
437
502
|
|
|
438
|
-
if lane < 0 or lane >= destination_task.get_lane_count():
|
|
439
|
-
raise Exception(
|
|
440
|
-
f"Unable to invoke task {destination_task_id} in lane {lane} because it is not a valid lane for the task."
|
|
441
|
-
)
|
|
442
|
-
|
|
443
503
|
if force_sync or env.get_force_sync_mode():
|
|
444
|
-
|
|
504
|
+
if is_external_task:
|
|
505
|
+
raise NotImplementedError(
|
|
506
|
+
f"Unable to run external task {destination_task_id} locally."
|
|
507
|
+
)
|
|
445
508
|
# Sync invocation with mock event/context
|
|
446
509
|
current_task_id = self.current_task_id
|
|
447
510
|
current_lane = self.get_current_lane()
|
|
@@ -462,7 +525,7 @@ class AsyncLambdaController:
|
|
|
462
525
|
self.set_current_lane(current_lane)
|
|
463
526
|
self.set_current_task_id(current_task_id)
|
|
464
527
|
else:
|
|
465
|
-
entries = []
|
|
528
|
+
entries: List[dict] = []
|
|
466
529
|
for i, sqs_payload in enumerate(sqs_payloads):
|
|
467
530
|
if isinstance(delay, Sequence):
|
|
468
531
|
_delay = delay[i]
|
|
@@ -475,13 +538,27 @@ class AsyncLambdaController:
|
|
|
475
538
|
"Id": f"index_{index + i}",
|
|
476
539
|
}
|
|
477
540
|
)
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
541
|
+
if is_external_task:
|
|
542
|
+
url = f"https://sqs.{env.get_aws_region()}.amazonaws.com/{env.get_aws_account_id()}/{destination_task_id}"
|
|
543
|
+
else:
|
|
544
|
+
url = destination_task.get_managed_queue_url(lane=lane)
|
|
545
|
+
failed_messages = []
|
|
546
|
+
for _ in range(5):
|
|
547
|
+
response = get_sqs_client().send_message_batch(
|
|
548
|
+
QueueUrl=url,
|
|
549
|
+
Entries=entries,
|
|
550
|
+
)
|
|
551
|
+
failed_messages: List[dict] = response.get("Failed", [])
|
|
552
|
+
if len(failed_messages) == 0:
|
|
553
|
+
return
|
|
554
|
+
logger.warning(failed_messages)
|
|
555
|
+
logger.warning(f"{len(failed_messages)} messages failed to send.")
|
|
556
|
+
failed_message_ids = {message["Id"] for message in failed_messages}
|
|
557
|
+
entries = [
|
|
558
|
+
entry for entry in entries if entry["Id"] in failed_message_ids
|
|
559
|
+
]
|
|
560
|
+
logger.error(failed_messages)
|
|
561
|
+
raise Exception(f"Failed to send {len(failed_messages)} messages.")
|
|
485
562
|
|
|
486
563
|
def new_payload(
|
|
487
564
|
self,
|
|
@@ -504,6 +581,14 @@ class AsyncLambdaController:
|
|
|
504
581
|
"destination_task_id": destination_task_id,
|
|
505
582
|
"invocation_id": invocation_id,
|
|
506
583
|
}
|
|
584
|
+
is_external_task = False
|
|
585
|
+
if (
|
|
586
|
+
self.get_task(destination_task_id) is None
|
|
587
|
+
and destination_task_id in self.external_async_tasks
|
|
588
|
+
):
|
|
589
|
+
is_external_task = True
|
|
590
|
+
raw_sqs_body["source_app"] = config.name
|
|
591
|
+
|
|
507
592
|
serialized_payload = json.dumps(payload, cls=PayloadEncoder)
|
|
508
593
|
payload_size = len(serialized_payload.encode())
|
|
509
594
|
if payload_size < 250_000: # we need to double encode to be sure
|
|
@@ -512,6 +597,10 @@ class AsyncLambdaController:
|
|
|
512
597
|
if force_sync or env.get_force_sync_mode():
|
|
513
598
|
raw_sqs_body["payload"] = serialized_payload
|
|
514
599
|
elif payload_size >= 250_000: # payload is bigger than max SQS size
|
|
600
|
+
if is_external_task:
|
|
601
|
+
raise NotImplementedError(
|
|
602
|
+
"Payload is too large for SQS and S3 payloads are not supported with external invocations"
|
|
603
|
+
)
|
|
515
604
|
date_part = datetime.now(tz=timezone.utc).strftime("%Y/%m/%d")
|
|
516
605
|
key = f"{date_part}/{uuid4().hex}.json"
|
|
517
606
|
logger.info(f"Utilizing S3 Payload because of payload size. Key: {key}")
|
|
@@ -529,6 +618,9 @@ class AsyncLambdaController:
|
|
|
529
618
|
for task in controller.tasks.values():
|
|
530
619
|
self.add_task(task)
|
|
531
620
|
|
|
621
|
+
for task_id in controller.external_async_tasks:
|
|
622
|
+
self.external_async_tasks.add(task_id)
|
|
623
|
+
|
|
532
624
|
def async_invoke(
|
|
533
625
|
self,
|
|
534
626
|
task_id: str,
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import os
|
|
3
|
+
from typing import Optional
|
|
4
|
+
|
|
5
|
+
from .client import get_sts_client
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class AWSConfig:
|
|
9
|
+
_aws_region: Optional[str] = None
|
|
10
|
+
_account_id: Optional[str] = None
|
|
11
|
+
|
|
12
|
+
@property
|
|
13
|
+
def aws_region(self):
|
|
14
|
+
if self._aws_region:
|
|
15
|
+
return self._aws_region
|
|
16
|
+
self._aws_region = os.environ.get(
|
|
17
|
+
"AWS_REGION", os.environ.get("AWS_DEFAULT_REGION")
|
|
18
|
+
)
|
|
19
|
+
if self._aws_region is None:
|
|
20
|
+
raise ValueError("Unable to find AWS_REGION for constructing ARN or URL")
|
|
21
|
+
return self._aws_region
|
|
22
|
+
|
|
23
|
+
@property
|
|
24
|
+
def account_id(self):
|
|
25
|
+
if self._account_id:
|
|
26
|
+
return self._account_id
|
|
27
|
+
self._account_id = os.environ.get("ASYNC_LAMBDA_ACCOUNT_ID")
|
|
28
|
+
if self._account_id is not None:
|
|
29
|
+
return self._account_id
|
|
30
|
+
self._account_id = get_sts_client().get_caller_identity().get("Account")
|
|
31
|
+
logging.info(f"Fetched account_id from sts: {self._account_id}")
|
|
32
|
+
if self._account_id is None:
|
|
33
|
+
raise ValueError("Unable to get ACCOUNT_ID from env or STS.")
|
|
34
|
+
return self._account_id
|
|
35
|
+
|
|
36
|
+
def reset(self):
|
|
37
|
+
self._aws_region = None
|
|
38
|
+
self._account_id = None
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
aws_config = AWSConfig()
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def reset():
|
|
45
|
+
aws_config.reset()
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def is_build_mode() -> bool:
|
|
49
|
+
return bool(os.environ.get("ASYNC_LAMBDA_BUILD_MODE", False))
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def get_aws_region() -> str:
|
|
53
|
+
return aws_config.aws_region
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def get_aws_account_id() -> str:
|
|
57
|
+
return aws_config.account_id
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def get_payload_bucket() -> str:
|
|
61
|
+
return os.environ["ASYNC_LAMBDA_PAYLOAD_S3_BUCKET"]
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def get_current_task_id() -> str:
|
|
65
|
+
return os.environ["ASYNC_LAMBDA_TASK_ID"]
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def is_cloud() -> bool:
|
|
69
|
+
return bool(os.environ.get("AWS_LAMBDA_FUNCTION_NAME"))
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def enable_force_sync_mode():
|
|
73
|
+
os.environ["ASYNC_LAMBDA_FORCE_SYNC"] = "1"
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def disable_force_sync_mode():
|
|
77
|
+
del os.environ["ASYNC_LAMBDA_FORCE_SYNC"]
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def get_force_sync_mode() -> bool:
|
|
81
|
+
return bool(os.environ.get("ASYNC_LAMBDA_FORCE_SYNC", ""))
|
|
@@ -2,7 +2,17 @@ import inspect
|
|
|
2
2
|
import json
|
|
3
3
|
import re
|
|
4
4
|
from enum import Enum
|
|
5
|
-
from typing import
|
|
5
|
+
from typing import (
|
|
6
|
+
TYPE_CHECKING,
|
|
7
|
+
Any,
|
|
8
|
+
Callable,
|
|
9
|
+
Generic,
|
|
10
|
+
List,
|
|
11
|
+
Optional,
|
|
12
|
+
Set,
|
|
13
|
+
TypeVar,
|
|
14
|
+
Union,
|
|
15
|
+
)
|
|
6
16
|
|
|
7
17
|
from async_lambda.util import make_cf_tags
|
|
8
18
|
|
|
@@ -322,10 +332,21 @@ class AsyncLambdaTask(Generic[EventType, RT]):
|
|
|
322
332
|
return [self.trigger_config["queue_arn"]]
|
|
323
333
|
return []
|
|
324
334
|
|
|
335
|
+
@classmethod
|
|
336
|
+
def get_policy_external_task_resources(cls, external_task_id: str) -> list:
|
|
337
|
+
return [
|
|
338
|
+
{
|
|
339
|
+
"Fn::Sub": "arn:aws:sqs:${AWS::Region}:${AWS::AccountId}:external_task_id".replace(
|
|
340
|
+
"external_task_id", external_task_id
|
|
341
|
+
)
|
|
342
|
+
}
|
|
343
|
+
]
|
|
344
|
+
|
|
325
345
|
def get_sam_template(
|
|
326
346
|
self,
|
|
327
347
|
module: str,
|
|
328
348
|
tasks: List["AsyncLambdaTask"],
|
|
349
|
+
external_async_tasks: Set[str],
|
|
329
350
|
config_dict: dict,
|
|
330
351
|
stage: Optional[str] = None,
|
|
331
352
|
) -> dict:
|
|
@@ -358,6 +379,12 @@ class AsyncLambdaTask(Generic[EventType, RT]):
|
|
|
358
379
|
for task in tasks
|
|
359
380
|
if task.trigger_type in MANAGED_SQS_TASK_TYPES
|
|
360
381
|
for resource in task.get_policy_sqs_resources()
|
|
382
|
+
] + [
|
|
383
|
+
resource
|
|
384
|
+
for external_async_task_id in external_async_tasks
|
|
385
|
+
for resource in self.get_policy_external_task_resources(
|
|
386
|
+
external_async_task_id
|
|
387
|
+
)
|
|
361
388
|
]
|
|
362
389
|
if len(managed_tasks_resources) > 0:
|
|
363
390
|
policy_statements.append(
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
def is_build_mode() -> bool:
|
|
5
|
-
return bool(os.environ.get("ASYNC_LAMBDA_BUILD_MODE", False))
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
def get_aws_region() -> str:
|
|
9
|
-
return os.environ.get("AWS_REGION", "local")
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
def get_aws_account_id() -> str:
|
|
13
|
-
return os.environ.get("ASYNC_LAMBDA_ACCOUNT_ID", "localaccount")
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
def get_payload_bucket() -> str:
|
|
17
|
-
return os.environ["ASYNC_LAMBDA_PAYLOAD_S3_BUCKET"]
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
def get_current_task_id() -> str:
|
|
21
|
-
return os.environ["ASYNC_LAMBDA_TASK_ID"]
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
def is_cloud() -> bool:
|
|
25
|
-
return bool(os.environ.get("AWS_LAMBDA_FUNCTION_NAME"))
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
def enable_force_sync_mode():
|
|
29
|
-
os.environ["ASYNC_LAMBDA_FORCE_SYNC"] = "1"
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
def disable_force_sync_mode():
|
|
33
|
-
del os.environ["ASYNC_LAMBDA_FORCE_SYNC"]
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
def get_force_sync_mode() -> bool:
|
|
37
|
-
return bool(os.environ.get("ASYNC_LAMBDA_FORCE_SYNC", ""))
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{async-lambda-unstable-0.4.18 → async-lambda-unstable-0.5.2}/async_lambda/models/__init__.py
RENAMED
|
File without changes
|
{async-lambda-unstable-0.4.18 → async-lambda-unstable-0.5.2}/async_lambda/models/api_response.py
RENAMED
|
File without changes
|
|
File without changes
|
{async-lambda-unstable-0.4.18 → async-lambda-unstable-0.5.2}/async_lambda/models/events/__init__.py
RENAMED
|
File without changes
|
{async-lambda-unstable-0.4.18 → async-lambda-unstable-0.5.2}/async_lambda/models/events/api_event.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{async-lambda-unstable-0.4.18 → async-lambda-unstable-0.5.2}/async_lambda/models/mock/mock_event.py
RENAMED
|
File without changes
|
{async-lambda-unstable-0.4.18 → async-lambda-unstable-0.5.2}/async_lambda/payload_encoder.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|