modmex-lambda 0.3.0__py3-none-any.whl → 0.4.0__py3-none-any.whl

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 (104) hide show
  1. modmex_lambda/__init__.py +20 -11
  2. modmex_lambda/connectors/__init__.py +28 -0
  3. modmex_lambda/connectors/cloudwatch.py +17 -0
  4. modmex_lambda/connectors/dynamodb.py +123 -0
  5. modmex_lambda/connectors/eventbridge.py +19 -0
  6. modmex_lambda/connectors/icloudwatch.py +14 -0
  7. modmex_lambda/connectors/idynamodb.py +68 -0
  8. modmex_lambda/connectors/ieventbridge.py +14 -0
  9. modmex_lambda/connectors/ilambda.py +14 -0
  10. modmex_lambda/connectors/is3.py +30 -0
  11. modmex_lambda/connectors/isns.py +20 -0
  12. modmex_lambda/connectors/isqs.py +21 -0
  13. modmex_lambda/connectors/lambda_.py +17 -0
  14. modmex_lambda/connectors/module.py +67 -0
  15. modmex_lambda/connectors/s3.py +43 -0
  16. modmex_lambda/connectors/sns.py +31 -0
  17. modmex_lambda/connectors/sqs.py +31 -0
  18. modmex_lambda/data_classes/__init__.py +107 -24
  19. modmex_lambda/dependencies.py +106 -0
  20. modmex_lambda/event_handler/__init__.py +11 -10
  21. modmex_lambda/event_handler/api_gateway.py +7 -7
  22. modmex_lambda/event_handler/dependencies/__init__.py +30 -6
  23. modmex_lambda/event_handler/dependencies/depends.py +4 -52
  24. modmex_lambda/event_handler/types.py +1 -1
  25. modmex_lambda/logging.py +48 -14
  26. modmex_lambda/stream/__init__.py +3 -0
  27. modmex_lambda/stream/events/__init__.py +0 -0
  28. modmex_lambda/stream/events/dynamodb.py +123 -0
  29. modmex_lambda/stream/events/kinesis.py +44 -0
  30. modmex_lambda/stream/events/s3.py +66 -0
  31. modmex_lambda/stream/events/sns.py +54 -0
  32. modmex_lambda/stream/events/sqs.py +46 -0
  33. modmex_lambda/stream/filters/__init__.py +0 -0
  34. modmex_lambda/stream/filters/content.py +9 -0
  35. modmex_lambda/stream/filters/event_type.py +17 -0
  36. modmex_lambda/stream/filters/latch.py +21 -0
  37. modmex_lambda/stream/filters/skip.py +18 -0
  38. modmex_lambda/stream/flavors/__init__.py +0 -0
  39. modmex_lambda/stream/flavors/base_flavor.py +140 -0
  40. modmex_lambda/stream/flavors/cdc.py +70 -0
  41. modmex_lambda/stream/flavors/collect.py +105 -0
  42. modmex_lambda/stream/flavors/correlate.py +114 -0
  43. modmex_lambda/stream/flavors/evaluate.py +235 -0
  44. modmex_lambda/stream/flavors/expired.py +104 -0
  45. modmex_lambda/stream/flavors/iflavor.py +19 -0
  46. modmex_lambda/stream/flavors/job.py +294 -0
  47. modmex_lambda/stream/flavors/materialize.py +65 -0
  48. modmex_lambda/stream/flavors/s3.py +63 -0
  49. modmex_lambda/stream/flavors/sns.py +59 -0
  50. modmex_lambda/stream/flavors/task.py +135 -0
  51. modmex_lambda/stream/flavors/update.py +171 -0
  52. modmex_lambda/stream/irules_registry.py +18 -0
  53. modmex_lambda/stream/operators/__init__.py +1 -0
  54. modmex_lambda/stream/operators/cloudwatch.py +29 -0
  55. modmex_lambda/stream/operators/dynamodb.py +391 -0
  56. modmex_lambda/stream/operators/ioperator.py +14 -0
  57. modmex_lambda/stream/operators/lambda_.py +29 -0
  58. modmex_lambda/stream/operators/publisher.py +99 -0
  59. modmex_lambda/stream/operators/s3.py +131 -0
  60. modmex_lambda/stream/operators/sns.py +58 -0
  61. modmex_lambda/stream/operators/sqs.py +83 -0
  62. modmex_lambda/stream/rules_registry.py +38 -0
  63. modmex_lambda/stream/runner.py +93 -0
  64. modmex_lambda/stream/sources/__init__.py +53 -0
  65. modmex_lambda/stream/sources/base.py +60 -0
  66. modmex_lambda/stream/sources/dynamodb.py +71 -0
  67. modmex_lambda/stream/sources/kinesis.py +51 -0
  68. modmex_lambda/stream/sources/s3.py +51 -0
  69. modmex_lambda/stream/sources/sns.py +51 -0
  70. modmex_lambda/stream/sources/sqs.py +51 -0
  71. modmex_lambda/stream/utils/__init__.py +0 -0
  72. modmex_lambda/stream/utils/apigateway.py +41 -0
  73. modmex_lambda/stream/utils/aws.py +6 -0
  74. modmex_lambda/stream/utils/batch.py +9 -0
  75. modmex_lambda/stream/utils/cloudwatch.py +11 -0
  76. modmex_lambda/stream/utils/concurrency.py +54 -0
  77. modmex_lambda/stream/utils/contracts.py +45 -0
  78. modmex_lambda/stream/utils/data_classes/__init__.py +0 -0
  79. modmex_lambda/stream/utils/data_classes/dynamodb.py +17 -0
  80. modmex_lambda/stream/utils/decorators.py +9 -0
  81. modmex_lambda/stream/utils/dynamodb.py +140 -0
  82. modmex_lambda/stream/utils/eventbridge.py +25 -0
  83. modmex_lambda/stream/utils/faults.py +100 -0
  84. modmex_lambda/stream/utils/filters.py +15 -0
  85. modmex_lambda/stream/utils/json_encoder.py +12 -0
  86. modmex_lambda/stream/utils/lambda_.py +11 -0
  87. modmex_lambda/stream/utils/operators.py +76 -0
  88. modmex_lambda/stream/utils/opt.py +15 -0
  89. modmex_lambda/stream/utils/pluralize.py +13 -0
  90. modmex_lambda/stream/utils/print.py +24 -0
  91. modmex_lambda/stream/utils/retry.py +28 -0
  92. modmex_lambda/stream/utils/s3.py +52 -0
  93. modmex_lambda/stream/utils/sns.py +11 -0
  94. modmex_lambda/stream/utils/split.py +32 -0
  95. modmex_lambda/stream/utils/sqs.py +19 -0
  96. modmex_lambda/stream/utils/tags.py +33 -0
  97. modmex_lambda/stream/utils/time.py +17 -0
  98. modmex_lambda/stream/utils/uow.py +110 -0
  99. modmex_lambda-0.4.0.dist-info/METADATA +1107 -0
  100. modmex_lambda-0.4.0.dist-info/RECORD +138 -0
  101. modmex_lambda-0.3.0.dist-info/METADATA +0 -598
  102. modmex_lambda-0.3.0.dist-info/RECORD +0 -48
  103. {modmex_lambda-0.3.0.dist-info → modmex_lambda-0.4.0.dist-info}/WHEEL +0 -0
  104. {modmex_lambda-0.3.0.dist-info → modmex_lambda-0.4.0.dist-info}/licenses/LICENSE +0 -0
modmex_lambda/__init__.py CHANGED
@@ -7,51 +7,60 @@ from typing import TYPE_CHECKING, Any
7
7
 
8
8
  if TYPE_CHECKING:
9
9
  from .event_handler import (
10
- ApiGatewayHttpResolver,
11
- ApiGatewayRestResolver,
10
+ APIGatewayHttpResolver,
11
+ APIGatewayRestResolver,
12
12
  Response,
13
13
  )
14
14
  from .event_handler.request import Request
15
15
  from .event_sources import event_source
16
- from .event_handler.dependencies.depends import (
16
+ from .connectors import AwsConnectorsModule
17
+ from .dependencies import (
17
18
  DefaultDependencyResolver,
18
19
  DependencyResolver,
19
- Depends,
20
20
  InjectorDependencyResolver,
21
+ create_dependency_resolver,
22
+ default_dependency_resolver,
21
23
  )
24
+ from .event_handler.dependencies.depends import Depends
22
25
  from .logging import Logger
23
26
  from .parser import event_parser, parse
24
27
  from .validation import ModmexValidator, ValidationError
25
28
 
26
29
  _EXPORTS = {
27
- "ApiGatewayHttpResolver": ("modmex_lambda.event_handler", "ApiGatewayHttpResolver"),
28
- "ApiGatewayRestResolver": ("modmex_lambda.event_handler", "ApiGatewayRestResolver"),
30
+ "APIGatewayHttpResolver": ("modmex_lambda.event_handler", "APIGatewayHttpResolver"),
31
+ "APIGatewayRestResolver": ("modmex_lambda.event_handler", "APIGatewayRestResolver"),
29
32
  "Request": ("modmex_lambda.event_handler.request", "Request"),
30
33
  "Response": ("modmex_lambda.event_handler", "Response"),
31
34
  "parse": ("modmex_lambda.parser", "parse"),
32
35
  "event_parser": ("modmex_lambda.parser", "event_parser"),
33
36
  "event_source": ("modmex_lambda.event_sources", "event_source"),
34
- "DefaultDependencyResolver": ("modmex_lambda.event_handler.dependencies.depends", "DefaultDependencyResolver"),
35
- "DependencyResolver": ("modmex_lambda.event_handler.dependencies.depends", "DependencyResolver"),
37
+ "AwsConnectorsModule": ("modmex_lambda.connectors", "AwsConnectorsModule"),
38
+ "DefaultDependencyResolver": ("modmex_lambda.dependencies", "DefaultDependencyResolver"),
39
+ "DependencyResolver": ("modmex_lambda.dependencies", "DependencyResolver"),
36
40
  "Depends": ("modmex_lambda.event_handler.dependencies.depends", "Depends"),
37
- "InjectorDependencyResolver": ("modmex_lambda.event_handler.dependencies.depends", "InjectorDependencyResolver"),
41
+ "InjectorDependencyResolver": ("modmex_lambda.dependencies", "InjectorDependencyResolver"),
42
+ "create_dependency_resolver": ("modmex_lambda.dependencies", "create_dependency_resolver"),
43
+ "default_dependency_resolver": ("modmex_lambda.dependencies", "default_dependency_resolver"),
38
44
  "Logger": ("modmex_lambda.logging", "Logger"),
39
45
  "ModmexValidator": ("modmex_lambda.validation", "ModmexValidator"),
40
46
  "ValidationError": ("modmex_lambda.validation", "ValidationError"),
41
47
  }
42
48
 
43
49
  __all__ = [
44
- "ApiGatewayHttpResolver",
45
- "ApiGatewayRestResolver",
50
+ "APIGatewayHttpResolver",
51
+ "APIGatewayRestResolver",
46
52
  "Request",
47
53
  "Response",
48
54
  "parse",
49
55
  "event_parser",
50
56
  "event_source",
57
+ "AwsConnectorsModule",
51
58
  "DefaultDependencyResolver",
52
59
  "DependencyResolver",
53
60
  "Depends",
54
61
  "InjectorDependencyResolver",
62
+ "create_dependency_resolver",
63
+ "default_dependency_resolver",
55
64
  "Logger",
56
65
  "ModmexValidator",
57
66
  "ValidationError",
@@ -0,0 +1,28 @@
1
+ from __future__ import annotations
2
+
3
+ from importlib import import_module
4
+ from typing import TYPE_CHECKING, Any
5
+
6
+ if TYPE_CHECKING:
7
+ from modmex_lambda.connectors.module import AwsConnectorsModule
8
+
9
+ _EXPORTS = {
10
+ "AwsConnectorsModule": ("modmex_lambda.connectors.module", "AwsConnectorsModule"),
11
+ }
12
+
13
+ __all__ = ["AwsConnectorsModule"]
14
+
15
+
16
+ def __getattr__(name: str) -> Any:
17
+ target = _EXPORTS.get(name)
18
+ if target is None:
19
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
20
+
21
+ module_name, attr = target
22
+ value = getattr(import_module(module_name), attr)
23
+ globals()[name] = value
24
+ return value
25
+
26
+
27
+ def __dir__() -> list[str]:
28
+ return sorted([*globals().keys(), *__all__])
@@ -0,0 +1,17 @@
1
+ from modmex_lambda.connectors.icloudwatch import ICloudWatchConnector
2
+
3
+
4
+ class Connector(ICloudWatchConnector):
5
+
6
+ def __init__(self, client = None) -> None:
7
+ self._client = client
8
+
9
+ @property
10
+ def client(self):
11
+ if not self._client:
12
+ import boto3
13
+ self._client = boto3.client('cloudwatch')
14
+ return self._client
15
+
16
+ def put(self, input_params):
17
+ return self.client.put_metric_data(**input_params)
@@ -0,0 +1,123 @@
1
+ from functools import reduce
2
+ from typing import Iterable
3
+
4
+ from modmex_lambda.connectors.idynamodb import IDynamodbConnector
5
+ from modmex_lambda.stream.utils.retry import (
6
+ assert_max_retries,
7
+ DEFAULT_RETRY_CONFIG,
8
+ wait,
9
+ get_delay
10
+ )
11
+
12
+
13
+ class Connector(IDynamodbConnector):
14
+
15
+ def __init__(self,# pylint: disable=W0102
16
+ table_name = 'undefined',
17
+ retry_config = DEFAULT_RETRY_CONFIG,
18
+ client = None) -> None:
19
+ self.table_name = table_name
20
+ self._client = client
21
+ self.retry_config = retry_config
22
+
23
+ @property
24
+ def client(self):
25
+ if not self._client:
26
+ import boto3
27
+ self._client = boto3.resource('dynamodb')
28
+ return self._client
29
+
30
+ def get(self, input_params):
31
+ return self.client.Table(self.table_name).get_item(
32
+ **input_params
33
+ )
34
+
35
+ def update(self, input_params):
36
+ return self.client.Table(self.table_name).update_item(
37
+ **input_params
38
+ )
39
+
40
+ def put(self, input_params):
41
+ return self.client.Table(self.table_name).put_item(
42
+ **input_params
43
+ )
44
+
45
+ def query(self, input_params):
46
+ return self.client.Table(self.table_name).query(
47
+ **input_params
48
+ )
49
+
50
+ def query_page(self, input_params):
51
+ return self.query(input_params)
52
+
53
+ def scan(self, input_params):
54
+ return self.client.Table(self.table_name).scan(
55
+ **input_params
56
+ )
57
+
58
+ def query_all(self, input_params):
59
+ items = []
60
+ while True:
61
+
62
+ result = self.client.Table(self.table_name).query(
63
+ **input_params
64
+ )
65
+ for item in result['Items']:
66
+ items.append(item)
67
+
68
+ if 'LastEvaluatedKey' in result and result['LastEvaluatedKey']:
69
+ input_params['ExclusiveStartKey'] = result['LastEvaluatedKey']
70
+ else:
71
+ break
72
+ return items
73
+
74
+ def batch_get(self, input_params):
75
+ return self._batch_get(input_params, [])
76
+
77
+ def _batch_get(self, params, attempts):
78
+ assert_max_retries(attempts, self.retry_config['max_retries'])
79
+ wait(get_delay(self.retry_config['retry_wait'], len(attempts)))
80
+ resp = self.client.batch_get_item(**params)
81
+ if 'UnprocessedKeys' in resp and resp['UnprocessedKeys']:
82
+ return self._batch_get(
83
+ unprocessed(params, resp),
84
+ [*attempts, resp]
85
+ )
86
+ return accumulate(attempts, resp)
87
+
88
+ def bulk_insert(self, items: Iterable):
89
+ with self.client.Table(self.table_name).batch_writer() as batch:
90
+ for item in items:
91
+ batch.put_item(Item=item)
92
+
93
+ def bulk_delete(self, items: Iterable):
94
+ with self.client.Table(self.table_name).batch_writer() as batch:
95
+ for key in items:
96
+ batch.delete_item(Key=key)
97
+
98
+
99
+ def unprocessed(params, resp):
100
+ return {
101
+ **params,
102
+ 'RequestItems': resp['UnprocessedKeys']
103
+ }
104
+
105
+ def accumulate(attempts, resp):
106
+ def reducer(a, c):
107
+ return {
108
+ **a,
109
+ 'Responses': reduce(
110
+ lambda a2, c2: {
111
+ **a2,
112
+ c2: [
113
+ *a2.get(c2, []),
114
+ *a['Responses'].get(c2, [])
115
+ ]
116
+ },
117
+ list(a['Responses']),
118
+ {**c['Responses']}
119
+ ),
120
+ 'attempts': [*attempts, resp]
121
+ }
122
+
123
+ return reduce(reducer, reversed(attempts), resp)
@@ -0,0 +1,19 @@
1
+
2
+ from modmex_lambda.connectors.ieventbridge import IEventBridgeConnector
3
+
4
+
5
+ class Connector(IEventBridgeConnector):
6
+
7
+ def __init__(self, client = None) -> None:
8
+ self._client = client
9
+
10
+ @property
11
+ def client(self):
12
+ if not self._client:
13
+ import boto3
14
+ self._client = boto3.client('events')
15
+ return self._client
16
+
17
+ def put_events(self, params):
18
+ response = self.client.put_events(**params)
19
+ return response
@@ -0,0 +1,14 @@
1
+ from abc import ABC, abstractmethod
2
+ from typing import Any, Dict
3
+
4
+
5
+ class ICloudWatchConnector(ABC):
6
+ @property
7
+ def client(self) -> Any:
8
+ """Returns the CloudWatch client"""
9
+ raise NotImplementedError("client property must be implemented")
10
+
11
+ @abstractmethod
12
+ def put(self, input_params: Dict[str, Any]) -> Dict[str, Any]:
13
+ """Puts metric data into CloudWatch"""
14
+ raise NotImplementedError("put method must be implemented")
@@ -0,0 +1,68 @@
1
+ from abc import ABC, abstractmethod
2
+ from typing import Any, Dict, Iterable
3
+
4
+ class IDynamodbConnector(ABC):
5
+ table_name: str
6
+ retry_config: Dict[str, Any]
7
+
8
+ @property
9
+ def client(self) -> Any:
10
+ """Returns the DynamoDB resource"""
11
+ raise NotImplementedError("client property must be implemented")
12
+
13
+ @abstractmethod
14
+ def get(self, input_params: Dict[str, Any]) -> Dict[str, Any]:
15
+ """Retrieves an item from the table"""
16
+ raise NotImplementedError("get method must be implemented")
17
+
18
+ @abstractmethod
19
+ def update(self, input_params: Dict[str, Any]) -> Dict[str, Any]:
20
+ """Updates an item in the table"""
21
+ raise NotImplementedError("update method must be implemented")
22
+
23
+ @abstractmethod
24
+ def put(self, input_params: Dict[str, Any]) -> Dict[str, Any]:
25
+ """Puts an item into the table"""
26
+ raise NotImplementedError("put method must be implemented")
27
+
28
+ @abstractmethod
29
+ def query(self, input_params: Dict[str, Any]) -> Dict[str, Any]:
30
+ """Queries items from the table"""
31
+ raise NotImplementedError("query method must be implemented")
32
+
33
+ @abstractmethod
34
+ def query_all(self, input_params: Dict[str, Any]) -> list[Dict[str, Any]]:
35
+ """Queries all items, handling pagination"""
36
+ raise NotImplementedError("query_all method must be implemented")
37
+
38
+ @abstractmethod
39
+ def query_page(self, input_params: Dict[str, Any]) -> Dict[str, Any]:
40
+ """Queries one page of items"""
41
+ raise NotImplementedError("query_page method must be implemented")
42
+
43
+ @abstractmethod
44
+ def scan(self, input_params: Dict[str, Any]) -> Dict[str, Any]:
45
+ """Scans one page of items"""
46
+ raise NotImplementedError("scan method must be implemented")
47
+
48
+ @abstractmethod
49
+ def batch_get(self, input_params: Dict[str, Any]) -> Dict[str, Any]:
50
+ """Performs a batch get operation"""
51
+ raise NotImplementedError("batch_get method must be implemented")
52
+
53
+ @abstractmethod
54
+ def bulk_insert(self, items: Iterable[Dict[str, Any]]) -> None:
55
+ """Inserts multiple items using batch writer"""
56
+ raise NotImplementedError("bulk_insert method must be implemented")
57
+
58
+ @abstractmethod
59
+ def bulk_delete(self, items: Iterable[Dict[str, Any]]) -> None:
60
+ """Deletes multiple items using batch writer"""
61
+ raise NotImplementedError("bulk_delete method must be implemented")
62
+
63
+
64
+ class DynamoDbResource(ABC):
65
+
66
+ @abstractmethod
67
+ def Table(self, name: str):
68
+ raise NotImplementedError()
@@ -0,0 +1,14 @@
1
+ from abc import ABC, abstractmethod
2
+ from typing import Any, Dict
3
+
4
+ class IEventBridgeConnector(ABC):
5
+
6
+ @property
7
+ def client(self) -> Any:
8
+ """Returns the EventBridge client"""
9
+ raise NotImplementedError("client property must be implemented")
10
+
11
+ @abstractmethod
12
+ def put_events(self, params: Dict[str, Any]) -> Dict[str, Any]:
13
+ """Puts events into EventBridge"""
14
+ raise NotImplementedError("put_events method must be implemented")
@@ -0,0 +1,14 @@
1
+ from abc import ABC, abstractmethod
2
+ from typing import Any, Dict
3
+
4
+
5
+ class ILambdaConnector(ABC):
6
+ @property
7
+ def client(self) -> Any:
8
+ """Returns the Lambda client"""
9
+ raise NotImplementedError("client property must be implemented")
10
+
11
+ @abstractmethod
12
+ def invoke(self, params: Dict[str, Any]) -> Dict[str, Any]:
13
+ """Invokes a Lambda function"""
14
+ raise NotImplementedError("invoke method must be implemented")
@@ -0,0 +1,30 @@
1
+ from abc import ABC, abstractmethod
2
+ from typing import Any, Dict
3
+
4
+ class IS3Connector(ABC):
5
+ bucket_name: str
6
+
7
+ @property
8
+ def client(self) -> Any:
9
+ """Returns the S3 client"""
10
+ raise NotImplementedError("client property must be implemented")
11
+
12
+ @abstractmethod
13
+ def put_object(self, input_params: Dict[str, Any]) -> Dict[str, Any]:
14
+ """Uploads an object to the bucket"""
15
+ raise NotImplementedError("put_object method must be implemented")
16
+
17
+ @abstractmethod
18
+ def get_object(self, input_params: Dict[str, Any]) -> Dict[str, Any]:
19
+ """Retrieves an object from the bucket"""
20
+ raise NotImplementedError("get_object method must be implemented")
21
+
22
+ @abstractmethod
23
+ def list_objects(self, input_params: Dict[str, Any]) -> Dict[str, Any]:
24
+ """Lists objects in the bucket"""
25
+ raise NotImplementedError("list_objects method must be implemented")
26
+
27
+ @abstractmethod
28
+ def delete_object(self, input_params: Dict[str, Any]) -> Dict[str, Any]:
29
+ """Deletes an object from the bucket"""
30
+ raise NotImplementedError("delete_object method must be implemented")
@@ -0,0 +1,20 @@
1
+ from abc import ABC, abstractmethod
2
+ from typing import Any, Dict
3
+
4
+ class ISNSConnector(ABC):
5
+ topic_arn: str
6
+
7
+ @property
8
+ def client(self) -> Any:
9
+ """Returns the SNS client"""
10
+ raise NotImplementedError("client property must be implemented")
11
+
12
+ @abstractmethod
13
+ def publish(self, input_params: Dict[str, Any]) -> Dict[str, Any]:
14
+ """Publishes a message to the SNS topic"""
15
+ raise NotImplementedError("publish method must be implemented")
16
+
17
+ @abstractmethod
18
+ def publish_batch(self, input_params: Dict[str, Any]) -> Dict[str, Any]:
19
+ """Publishes a batch of messages to the SNS topic"""
20
+ raise NotImplementedError("publish_batch method must be implemented")
@@ -0,0 +1,21 @@
1
+ from abc import ABC, abstractmethod
2
+ from typing import Any, Dict
3
+
4
+
5
+ class ISQSConnector(ABC):
6
+ queue_url: str
7
+
8
+ @property
9
+ def client(self) -> Any:
10
+ """Returns the SQS client"""
11
+ raise NotImplementedError("client property must be implemented")
12
+
13
+ @abstractmethod
14
+ def send_message(self, input_params: Dict[str, Any]) -> Dict[str, Any]:
15
+ """Sends a message to SQS"""
16
+ raise NotImplementedError("send_message method must be implemented")
17
+
18
+ @abstractmethod
19
+ def send_message_batch(self, input_params: Dict[str, Any]) -> Dict[str, Any]:
20
+ """Sends a message batch to SQS"""
21
+ raise NotImplementedError("send_message_batch method must be implemented")
@@ -0,0 +1,17 @@
1
+ from modmex_lambda.connectors.ilambda import ILambdaConnector
2
+
3
+
4
+ class Connector(ILambdaConnector):
5
+
6
+ def __init__(self, client = None) -> None:
7
+ self._client = client
8
+
9
+ @property
10
+ def client(self):
11
+ if not self._client:
12
+ import boto3
13
+ self._client = boto3.client('lambda')
14
+ return self._client
15
+
16
+ def invoke(self, params):
17
+ return self.client.invoke(**params)
@@ -0,0 +1,67 @@
1
+ """Injector module with default AWS connector bindings."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from injector import Module, provider, singleton
6
+
7
+ from modmex_lambda.connectors.icloudwatch import ICloudWatchConnector
8
+ from modmex_lambda.connectors.idynamodb import IDynamodbConnector
9
+ from modmex_lambda.connectors.ieventbridge import IEventBridgeConnector
10
+ from modmex_lambda.connectors.ilambda import ILambdaConnector
11
+ from modmex_lambda.connectors.is3 import IS3Connector
12
+ from modmex_lambda.connectors.isns import ISNSConnector
13
+ from modmex_lambda.connectors.isqs import ISQSConnector
14
+
15
+
16
+ class AwsConnectorsModule(Module):
17
+ @singleton
18
+ @provider
19
+ def provide_dynamodb(self) -> IDynamodbConnector:
20
+ from modmex_lambda.connectors.dynamodb import Connector
21
+
22
+ return Connector()
23
+
24
+ @singleton
25
+ @provider
26
+ def provide_cloudwatch(self) -> ICloudWatchConnector:
27
+ from modmex_lambda.connectors.cloudwatch import Connector
28
+
29
+ return Connector()
30
+
31
+ @singleton
32
+ @provider
33
+ def provide_eventbridge(self) -> IEventBridgeConnector:
34
+ from modmex_lambda.connectors.eventbridge import Connector
35
+
36
+ return Connector()
37
+
38
+ @singleton
39
+ @provider
40
+ def provide_lambda(self) -> ILambdaConnector:
41
+ from modmex_lambda.connectors.lambda_ import Connector
42
+
43
+ return Connector()
44
+
45
+ @singleton
46
+ @provider
47
+ def provide_s3(self) -> IS3Connector:
48
+ from modmex_lambda.connectors.s3 import Connector
49
+
50
+ return Connector(None)
51
+
52
+ @singleton
53
+ @provider
54
+ def provide_sns(self) -> ISNSConnector:
55
+ from modmex_lambda.connectors.sns import Connector
56
+
57
+ return Connector()
58
+
59
+ @singleton
60
+ @provider
61
+ def provide_sqs(self) -> ISQSConnector:
62
+ from modmex_lambda.connectors.sqs import Connector
63
+
64
+ return Connector()
65
+
66
+
67
+ __all__ = ["AwsConnectorsModule"]
@@ -0,0 +1,43 @@
1
+ from modmex_lambda.connectors.is3 import IS3Connector
2
+
3
+
4
+ class Connector(IS3Connector):
5
+
6
+ def __init__(self, bucket_name, client = None) -> None:
7
+ self.bucket_name = bucket_name
8
+ self._client = client
9
+
10
+ @property
11
+ def client(self):
12
+ if not self._client:
13
+ import boto3
14
+ self._client = boto3.client('s3')
15
+ return self._client
16
+
17
+ def put_object(self, input_params):
18
+ params = {
19
+ 'Bucket': self.bucket_name,
20
+ **input_params
21
+ }
22
+ return self.client.put_object(**params)
23
+
24
+ def get_object(self, input_params):
25
+ params = {
26
+ 'Bucket': self.bucket_name,
27
+ **input_params
28
+ }
29
+ return self.client.get_object(**params)
30
+
31
+ def list_objects(self, input_params):
32
+ params = {
33
+ 'Bucket': self.bucket_name,
34
+ **input_params
35
+ }
36
+ return self.client.list_objects_v2(**params)
37
+
38
+ def delete_object(self, input_params):
39
+ params = {
40
+ 'Bucket': self.bucket_name,
41
+ **input_params
42
+ }
43
+ return self.client.delete_object(**params)
@@ -0,0 +1,31 @@
1
+ import os
2
+
3
+ from modmex_lambda.connectors.isns import ISNSConnector
4
+ from modmex_lambda.stream.utils.aws import get_region
5
+
6
+
7
+ class Connector(ISNSConnector):
8
+ def __init__(self, topic_arn = os.getenv('TOPIC_ARN'), client = None) -> None:
9
+ self.topic_arn = topic_arn
10
+ self._client = client
11
+
12
+ @property
13
+ def client(self):
14
+ if not self._client:
15
+ import boto3
16
+ self._client = boto3.client('sns', region_name=get_region(self.topic_arn))
17
+ return self._client
18
+
19
+ def publish(self, input_params):
20
+ params = {
21
+ 'TopicArn': self.topic_arn,
22
+ **input_params
23
+ }
24
+ return self.client.publish(**params)
25
+
26
+ def publish_batch(self, input_params):
27
+ params = {
28
+ 'TopicArn': self.topic_arn,
29
+ **input_params
30
+ }
31
+ return self.client.publish_batch(**params)
@@ -0,0 +1,31 @@
1
+ import os
2
+ from modmex_lambda.connectors.isqs import ISQSConnector
3
+
4
+
5
+ class Connector(ISQSConnector):
6
+
7
+ def __init__(self, queue_url = os.getenv('QUEUE_URL'), client = None) -> None:
8
+ self.queue_url = queue_url
9
+ self._client = client
10
+
11
+ @property
12
+ def client(self):
13
+ if not self._client:
14
+ import boto3
15
+ self._client = boto3.client('sqs')
16
+ return self._client
17
+
18
+ def send_message(self, input_params):
19
+ params = {
20
+ 'QueueUrl': self.queue_url,
21
+ **input_params
22
+ }
23
+
24
+ return self.client.send_message(**params)
25
+
26
+ def send_message_batch(self, input_params):
27
+ params = {
28
+ 'QueueUrl': self.queue_url,
29
+ **input_params
30
+ }
31
+ return self.client.send_message_batch(**params)