1+ """
2+ AWS Lambda implementation for the SeBs framework.
3+
4+ This module provides the AWS implementation of the FaaS System interface.
5+ It handles deploying and managing serverless functions on AWS Lambda,
6+ including code packaging, function creation, trigger management, and
7+ metrics collection.
8+ """
9+
110import math
211import os
312import shutil
2534
2635
2736class AWS (System ):
37+ """
38+ AWS Lambda implementation of the System interface.
39+
40+ This class implements the FaaS System interface for AWS Lambda,
41+ providing methods for deploying, invoking, and managing Lambda functions.
42+
43+ Attributes:
44+ logs_client: AWS CloudWatch Logs client
45+ cached: Whether AWS resources have been cached
46+ _config: AWS-specific configuration
47+ """
2848 logs_client = None
2949 cached = False
3050 _config : AWSConfig
3151
3252 @staticmethod
33- def name ():
53+ def name () -> str :
54+ """
55+ Get the name of this system.
56+
57+ Returns:
58+ str: System name ('aws')
59+ """
3460 return "aws"
3561
3662 @staticmethod
37- def typename ():
63+ def typename () -> str :
64+ """
65+ Get the type name of this system.
66+
67+ Returns:
68+ str: Type name ('AWS')
69+ """
3870 return "AWS"
3971
4072 @staticmethod
4173 def function_type () -> "Type[Function]" :
74+ """
75+ Get the function type for this system.
76+
77+ Returns:
78+ Type[Function]: LambdaFunction class
79+ """
4280 return LambdaFunction
4381
4482 @property
4583 def config (self ) -> AWSConfig :
84+ """
85+ Get the AWS-specific configuration.
86+
87+ Returns:
88+ AWSConfig: AWS configuration
89+ """
4690 return self ._config
4791
4892 @property
4993 def system_resources (self ) -> AWSSystemResources :
94+ """
95+ Get the AWS system resources manager.
96+
97+ Returns:
98+ AWSSystemResources: AWS resource manager
99+ """
50100 return cast (AWSSystemResources , self ._system_resources )
51101
52- """
53- :param cache_client: Function cache instance
54- :param config: Experiments config
55- :param docker_client: Docker instance
56- """
57-
58102 def __init__ (
59103 self ,
60104 sebs_config : SeBSConfig ,
@@ -63,6 +107,16 @@ def __init__(
63107 docker_client : docker .client ,
64108 logger_handlers : LoggingHandlers ,
65109 ):
110+ """
111+ Initialize the AWS system.
112+
113+ Args:
114+ sebs_config: SeBs system configuration
115+ config: AWS-specific configuration
116+ cache_client: Cache client for caching resources
117+ docker_client: Docker client for building images
118+ logger_handlers: Logging configuration
119+ """
66120 super ().__init__ (
67121 sebs_config ,
68122 cache_client ,
@@ -75,6 +129,16 @@ def __init__(
75129 self .nosql_storage : Optional [DynamoDB ] = None
76130
77131 def initialize (self , config : Dict [str , str ] = {}, resource_prefix : Optional [str ] = None ):
132+ """
133+ Initialize AWS resources.
134+
135+ Creates a boto3 session, initializes Lambda client, and prepares
136+ system resources and ECR client.
137+
138+ Args:
139+ config: Additional configuration parameters
140+ resource_prefix: Optional prefix for resource names
141+ """
78142 # thread-safe
79143 self .session = boto3 .session .Session (
80144 aws_access_key_id = self .config .credentials .access_key ,
@@ -89,31 +153,19 @@ def initialize(self, config: Dict[str, str] = {}, resource_prefix: Optional[str]
89153 )
90154
91155 def get_lambda_client (self ):
156+ """
157+ Get or create an AWS Lambda client.
158+
159+ Returns:
160+ boto3.client: Lambda client
161+ """
92162 if not hasattr (self , "client" ):
93163 self .client = self .session .client (
94164 service_name = "lambda" ,
95165 region_name = self .config .region ,
96166 )
97167 return self .client
98168
99- """
100- It would be sufficient to just pack the code and ship it as zip to AWS.
101- However, to have a compatible function implementation across providers,
102- we create a small module.
103- Issue: relative imports in Python when using storage wrapper.
104- Azure expects a relative import inside a module thus it's easier
105- to always create a module.
106-
107- Structure:
108- function
109- - function.py
110- - storage.py
111- - resources
112- handler.py
113-
114- benchmark: benchmark name
115- """
116-
117169 def package_code (
118170 self ,
119171 directory : str ,
@@ -124,6 +176,35 @@ def package_code(
124176 is_cached : bool ,
125177 container_deployment : bool ,
126178 ) -> Tuple [str , int , str ]:
179+ """
180+ Package code for deployment to AWS Lambda.
181+
182+ Creates a suitable deployment package with the following structure:
183+
184+ function/
185+ - function.py
186+ - storage.py
187+ - resources/
188+ handler.py
189+
190+ For container deployments, builds a Docker image and pushes it to ECR.
191+ For ZIP deployments, creates a ZIP package compatible with Lambda.
192+
193+ Args:
194+ directory: Path to the code directory
195+ language_name: Programming language name (e.g., 'python', 'nodejs')
196+ language_version: Language version (e.g., '3.8', '14')
197+ architecture: Target CPU architecture (e.g., 'x64', 'arm64')
198+ benchmark: Benchmark name
199+ is_cached: Whether code is already cached
200+ container_deployment: Whether to use container deployment
201+
202+ Returns:
203+ Tuple containing:
204+ - Path to the packaged code (ZIP file)
205+ - Size of the package in bytes
206+ - Container URI (if container_deployment=True, otherwise empty string)
207+ """
127208
128209 container_uri = ""
129210
@@ -163,13 +244,33 @@ def package_code(
163244 )
164245
165246 def _map_architecture (self , architecture : str ) -> str :
166-
247+ """
248+ Map architecture name to AWS Lambda-compatible format.
249+
250+ Args:
251+ architecture: Architecture name from SeBs (e.g., 'x64')
252+
253+ Returns:
254+ str: AWS Lambda-compatible architecture name (e.g., 'x86_64')
255+ """
167256 if architecture == "x64" :
168257 return "x86_64"
169258 return architecture
170259
171- def _map_language_runtime (self , language : str , runtime : str ):
172-
260+ def _map_language_runtime (self , language : str , runtime : str ) -> str :
261+ """
262+ Map language runtime to AWS Lambda-compatible format.
263+
264+ AWS uses different naming schemes for runtime versions.
265+ For example, Node.js uses '12.x' instead of '12'.
266+
267+ Args:
268+ language: Language name (e.g., 'nodejs', 'python')
269+ runtime: Runtime version (e.g., '12', '3.8')
270+
271+ Returns:
272+ str: AWS Lambda-compatible runtime version
273+ """
173274 # AWS uses different naming scheme for Node.js versions
174275 # For example, it's 12.x instead of 12.
175276 if language == "nodejs" :
@@ -183,6 +284,21 @@ def create_function(
183284 container_deployment : bool ,
184285 container_uri : str ,
185286 ) -> "LambdaFunction" :
287+ """
288+ Create or update an AWS Lambda function.
289+
290+ If the function already exists, it updates the code and configuration.
291+ Otherwise, it creates a new function with the specified parameters.
292+
293+ Args:
294+ code_package: Benchmark code package
295+ func_name: Name of the function
296+ container_deployment: Whether to use container deployment
297+ container_uri: URI of the container image (if container_deployment=True)
298+
299+ Returns:
300+ LambdaFunction: The created or updated Lambda function
301+ """
186302
187303 package = code_package .code_location
188304 benchmark = code_package .benchmark
@@ -296,24 +412,26 @@ def cached_function(self, function: Function):
296412 for trigger in function .triggers (Trigger .TriggerType .HTTP ):
297413 trigger .logging_handlers = self .logging_handlers
298414
299- """
300- Update function code and configuration on AWS.
301-
302- :param benchmark: benchmark name
303- :param name: function name
304- :param code_package: path to code package
305- :param code_size: size of code package in bytes
306- :param timeout: function timeout in seconds
307- :param memory: memory limit for function
308- """
309-
310415 def update_function (
311416 self ,
312417 function : Function ,
313418 code_package : Benchmark ,
314419 container_deployment : bool ,
315420 container_uri : str ,
316421 ):
422+ """
423+ Update an existing AWS Lambda function.
424+
425+ Updates the function code and waits for the update to complete.
426+ For container deployments, updates the container image.
427+ For ZIP deployments, uploads the code package directly or via S3.
428+
429+ Args:
430+ function: The function to update
431+ code_package: Benchmark code package
432+ container_deployment: Whether to use container deployment
433+ container_uri: URI of the container image (if container_deployment=True)
434+ """
317435 name = function .name
318436 function = cast (LambdaFunction , function )
319437
0 commit comments