Skip to content

Commit 6cf692d

Browse files
author
Javier Poveda-Panter
committed
add lambda application
1 parent 95f64f8 commit 6cf692d

File tree

8 files changed

+167
-0
lines changed

8 files changed

+167
-0
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
FROM public.ecr.aws/lambda/python:3.8
2+
3+
COPY requirements.txt ./
4+
5+
RUN python3.8 -m pip install -r requirements.txt -t .
6+
7+
COPY app.py ./
8+
9+
CMD ["app.lambda_handler"]

online-machine-learning-aws-lambda/app/lambda_inference/__init__.py

Whitespace-only changes.
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import json
2+
import boto3
3+
import os
4+
from aws_lambda_powertools import Logger
5+
from aws_lambda_powertools.utilities.data_classes import APIGatewayProxyEvent
6+
import tempfile
7+
import joblib
8+
9+
s3 = boto3.client('s3')
10+
logger = Logger(service="inference")
11+
12+
BUCKET_NAME = os.environ['BUCKET_NAME']
13+
model_name = 'model.joblib'
14+
15+
16+
def _download_model_from_s3(model_key):
17+
with tempfile.TemporaryFile() as fp:
18+
s3.download_fileobj(BUCKET_NAME, model_key, fp)
19+
fp.seek(0)
20+
model = joblib.load(fp)
21+
return model
22+
23+
24+
# Lambda handler code
25+
@logger.inject_lambda_context
26+
def lambda_handler(event, _):
27+
event = APIGatewayProxyEvent(event)
28+
logger.info(event.__dict__)
29+
# parse input event
30+
data = event.get('body')
31+
data = json.loads(data)
32+
data = data.get("data")
33+
# download current model from s3
34+
regr = _download_model_from_s3(model_name)
35+
# make prediction
36+
pred = regr.predict(data)
37+
# log prediction
38+
logger.info({
39+
"data": data,
40+
"prediction": pred,
41+
})
42+
43+
return {
44+
'statusCode': 200,
45+
'body': json.dumps(
46+
{
47+
"prediction": json.dumps(pred.tolist()),
48+
}
49+
)
50+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
aws-lambda-powertools==1.18.1
2+
scikit-learn==0.24.2
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
FROM public.ecr.aws/lambda/python:3.8
2+
3+
COPY requirements.txt ./
4+
5+
RUN python3.8 -m pip install -r requirements.txt -t .
6+
7+
COPY app.py ./
8+
9+
CMD ["app.lambda_handler"]

online-machine-learning-aws-lambda/app/lambda_training/__init__.py

Whitespace-only changes.
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
import json
2+
import boto3
3+
import os
4+
from aws_lambda_powertools import Logger
5+
from aws_lambda_powertools.utilities.data_classes import APIGatewayProxyEvent
6+
from sklearn import linear_model
7+
from sklearn.metrics import mean_squared_error, r2_score
8+
9+
import tempfile
10+
import joblib
11+
12+
s3 = boto3.client('s3')
13+
logger = Logger(service="training")
14+
15+
BUCKET_NAME = os.environ['BUCKET_NAME']
16+
model_name = 'model.joblib'
17+
18+
19+
def _upload_model_to_s3(model, model_key):
20+
with tempfile.TemporaryFile() as fp:
21+
joblib.dump(model, fp)
22+
fp.seek(0)
23+
s3.upload_fileobj(fp, BUCKET_NAME, model_key)
24+
25+
26+
def _train_regression_model(X_train, y_train):
27+
# Create linear regression object
28+
regr = linear_model.LinearRegression()
29+
# Train the model using the training sets
30+
regr.fit(X_train, y_train)
31+
return regr
32+
33+
34+
def _test_model(model, X_test, y_test):
35+
# Make predictions using the testing set
36+
y_pred = model.predict(X_test)
37+
# calculate quality coefficients
38+
mse = mean_squared_error(y_test, y_pred)
39+
r2 = r2_score(y_test, y_pred)
40+
return mse, r2
41+
42+
43+
def _parse_input(event):
44+
# extract input data from event
45+
data = event.get('body')
46+
d = json.loads(data)
47+
print('data', d.get("data"))
48+
logger.info(d)
49+
X = d["data"]['X']
50+
y = d["data"]['y']
51+
# Split the data into training/testing sets
52+
X_train = X[:-20]
53+
X_test = X[-20:]
54+
# Split the targets into training/testing sets
55+
y_train = y[:-20]
56+
y_test = y[-20:]
57+
return X_train, X_test, y_train, y_test
58+
59+
60+
# Lambda handler code
61+
@logger.inject_lambda_context
62+
def lambda_handler(event, _):
63+
event = APIGatewayProxyEvent(event)
64+
print(f'bucketname: {BUCKET_NAME}')
65+
logger.info(event.__dict__)
66+
# parse input event and split dataset
67+
X_train, X_test, y_train, y_test = _parse_input(event)
68+
# train regression model
69+
regr = _train_regression_model(X_train, y_train)
70+
# test model
71+
mse, r2 = _test_model(regr, X_test, y_test)
72+
logger.info({
73+
"message": "model training successful",
74+
'mean_squared_error': mse,
75+
'r_squared': r2
76+
})
77+
78+
# save trained model to s3
79+
_upload_model_to_s3(regr, model_name)
80+
logger.info({
81+
"message": "model saved to s3",
82+
'bucket_name': BUCKET_NAME,
83+
'model_name': model_name
84+
})
85+
86+
return {
87+
'statusCode': 200,
88+
'body': json.dumps(
89+
{
90+
'training': 'success',
91+
'mean_squared_error': mse,
92+
'r_squared': r2
93+
}
94+
)
95+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
aws-lambda-powertools==1.18.1
2+
scikit-learn==0.24.2

0 commit comments

Comments
 (0)