2. Tutorial¶
Juniper comes with a set of examples meant to show a developer working in the serverless domain, what he/she needs to do in order to easily adopt the tool.
To get started, make sure you clone the project and install juni:
>>> git clone git@github.com:eabglobal/juniper.git
>>> cd juniper
>>> python3 -m venv venv
>>> source venv/bin/activate
>>> pip install -e .
>>> cd examples/processing
2.1. Map Reduce Pipeline¶
The processing example is based on a map reduce pipeline in which the developer has defined multiple lambda functions. The first lambda function in the processing pipeline is the split_lambda. This function will be triggered whenever a json object is added to S3, the function will read the file and it will split it into two files.
The entire business logic associated with that function is:
import json
from commonlib import s3
from splitter.constants import BUCKET_NAME
def lambda_handler(event, context):
"""
Reads a source file from s3, splits the contents of the file in two and
adds the resulting values in the same bucket.
"""
file_name = event.get('source_file')
data = s3.read_json_file(BUCKET_NAME, file_name)
split_point = len(data) // 2
s3.write_json_file(BUCKET_NAME, 'to_map/part1.json', data[:split_point])
s3.write_json_file(BUCKET_NAME, 'to_map/part2.json', data[split_point:])
return {
'statusCode': 200,
'body': json.dumps({'message': 'Created 2 files'})
}
Note that this function has a reference to the commonlib.s3 object. The commonlib module lives along side the split_lambda function and it must be included in the split_lambda.zip artifact. Otherwise, the function will fail with a reference not found error.
The business logic of the remaining functions in the pipeline is not relevant to the example, however, the folder structure has a set of placeholders for them.
The manifest file, for the generation of the artifacts of this pipeline looks like:
functions:
split_step:
requirements: ./requirements.txt
include:
- ./commonlib
- ./split_lambda/splitter
map_step:
requirements: ./requirements.txt
include:
- ./commonlib
- ./map_lambda/mapper
reduce_step:
image: lambci/lambda:build-python3.7
requirements: ./reduce_lambda/requirements.txt
include:
- ./reduce_lambda/reducer/lambda_function.py
Note that in the definition of the split_step the includes section makes reference to the commonlib. This line indicates to juniper that the codebase inside the commonlib folder must be included in the .zip artifact for the split function.
>>> juni build
Removing processing_map_step-lambda_1 ... done
Removing processing_split_step-lambda_1 ... done
Removing processing_reduce_step-lambda_1 ... done
Removing network processing_default
Creating network "processing_default" with the default driver
Creating processing_split_step-lambda_1 ... done
Creating processing_map_step-lambda_1 ... done
Creating processing_reduce_step-lambda_1 ... done
Attaching to processing_split_step-lambda_1, processing_map_step-lambda_1, processing_reduce_step-lambda_1
split_step-lambda_1 | Starting to package split_step
reduce_step-lambda_1 | Starting to package reduce_step
map_step-lambda_1 | Starting to package map_step
reduce_step-lambda_1 | Finished packaging
processing_reduce_step-lambda_1 exited with code 0
split_step-lambda_1 | Finished packaging
processing_split_step-lambda_1 exited with code 0
map_step-lambda_1 | Finished packaging
processing_map_step-lambda_1 exited with code 0
Without any arguments, juni will by default look for a file named manifest.yml. From that file, juni will create the artifacts in a ./dist folder. The output of the above command creates the following artifacts:
>>> tree dist
dist
├── map_step.zip
├── reduce_step.zip
└── split_step.zip
Unzipping the split_step lambda we expect to have the contents of pip installing the request library; given that it is defined in the requirements.txt. The contents of the common lib and finally the splitter. All of which are defined in the manifest file.
>>> ls -larth
drwx------ 10 pdiazvargas 375838832 320B Jan 30 22:27 .
drwxr-xr-x 7 pdiazvargas 375838832 224B Jan 30 22:27 ..
drwxr-xr-x 15 pdiazvargas 375838832 480B Jan 31 2019 urllib3
drwxr-xr-x 4 pdiazvargas 375838832 128B Jan 31 2019 splitter
drwxr-xr-x 20 pdiazvargas 375838832 640B Jan 31 2019 requests
drwxr-xr-x 10 pdiazvargas 375838832 320B Jan 31 2019 idna
drwxr-xr-x 4 pdiazvargas 375838832 128B Jan 31 2019 commonlib
drwxr-xr-x 42 pdiazvargas 375838832 1.3K Jan 31 2019 chardet
drwxr-xr-x 6 pdiazvargas 375838832 192B Jan 31 2019 certifi
drwxr-xr-x 3 pdiazvargas 375838832 96B Jan 31 2019 bin