# Serverless Framework

## Introduction

* The Serverless Framework helps you develop and deploy [AWS Lambda](https://www.serverless.com/aws-lambda/) functions, along with the AWS infrastructure resources they require.&#x20;

```bash
npm i serverless -g
```

## Examples - Python

### Code

{% code title="app.py" %}
```python
def post_genkb_page(event:dict , context:dict):
    try:
        # listen to the event
        print("post genkb page raw event", event)
        input = SharePointMigrationInput(**json.loads(event.get("body",{})))
        print("input", input)
        # execute the logic
        res = asyncio.run(execute_post_genkb_page(input))
        print("res", res)
        # return res, must be followed as statusCode and body
        return {
            'statusCode': 200,
            'body': json.dumps(asdict(res))
        }
    except Exception as e:
        print("posting from sharepoint to genkb error", e)
        return {
            'statusCode': 400,
            'body': str(e)
        }
```
{% endcode %}

### Deployment Setting

{% code title="serverless.yml" %}
```yaml
service: genkb-sharepoint-migration
frameworkVersion: '4'
package:
  patterns:
    - '!node_modules/**'
    - '!venv/**'        # Exclude everything by default
    - '!.env'           # Exclude environment files
    - '!.git/**'        # Exclude git files
    - '!tests/**'       # Exclude test files
    - '!*.ipynb'
    - '!serverless.yml'
    - '!testData.json'
    - '!param_dict.yml'
    - '!secret_dict.yml'
    - '!env.yml'
    - '!deleteGenKBPageInput.json'
    - '!postGenKBPageInput.json'
provider:
  name: aws
  runtime: python3.12
  region: ap-east-1
  memorySize: 5000
  architecture: arm64
  timeout: 29
  # inject env from file
  environment: ${file(env.yml)}
  layers: 
    - arn:aws:lambda:ap-east-1:432797229265:layer:genkb-sharepoint-migration-dev-python-requirements:4

custom:
  pythonRequirements:
    # a layer is a ZIP archive that contains supplementary code or data
    # encapsulate the dependencies as a layer
    # reduce the size of deployment packages, separate core function logic from dependencies
    layer: true
    # this is necessary to avoid cross-platform build issues
    dockerizePip: true
    # explicitly pass the arm64 platform to the docker build
    dockerImage: public.ecr.aws/sam/build-python3.12:latest-arm64
    # explicitly tell pip to fetch the arm64 version of the package
    dockerRunCmdExtraArgs: [ '--platform', 'linux/arm64/v8' ]
    useStaticCache: false
# declare the trigger points
functions:  
  post_genkb_page:
    handler: app.post_genkb_page
    events:
      - http:
          path: genkb-page
          method: post   
  delete_genkb_page:
    handler: app.delete_genkb_page
    events:
      - http:
          path: genkb-page
          method: delete   
plugins:
  - serverless-python-requirements
```
{% endcode %}

<pre class="language-bash"><code class="lang-bash"><strong># Deploy a function with SIT stage
</strong><strong>serverless deploy -r ap-east-1 -s sit
</strong><strong># Test the lambda function locally by mocking the event
</strong>serverless invoke local --function delete_genkb_page --path deleteGenKBPageInput.json
</code></pre>

{% code title="deleteGenKBPageInput.json" %}
```json
{
    "body": "{\"path\":\"home/10748718/testing\"}"
}
```
{% endcode %}

## Examples - NodeJS

### Code

{% code title="index.ts" %}
```typescript
export const handler = async (event: any) => {
  console.log("file process lambda received event ->", event);
  const eventBody = JSON.parse(event?.Records[0].body) as EventBody;
  const { fileType } = eventBody;
  if (serviceMap[fileType]) {
    await serviceMap[fileType].generate(eventBody);
    return;
  }
  console.log("file process lambda not found action ->", event);
};
```
{% endcode %}

### Deployment Setting

{% code title="serverless.yml" %}
```yaml
service: file-processor

frameworkVersion: '3'

package:
  patterns:
    - '!venv/**'
    - '!node_modules/**'
    - '!Dockerfile'
    - '!.dockerignore'
    - '!.env'
    - '!env.*.yml'
    - '!testData.json'
    - '!param_dict.yml'
    - '!secret_dict.yml'
    - '!serverless-*.yml'
    - '!serverless.yml'

provider:
  name: aws
  runtime: nodejs18.x
  iam:
    role:
      statements:
        # Allow functions to read and write objects in a bucket
        - Effect: Allow
          Action:
            - 's3:GetObject'
            - 's3:PutObject'
            - 's3:DeleteObject'
          Resource:
            - 'arn:aws:s3:::hkt-gptass-file-history/*'
            - 'arn:aws:s3:::bot-builder-bot-usage-prod/*'
            - 'arn:aws:s3:::bot-builder-bot-usage-test/*'
        # xray permissions (required)
        - Effect: Allow
          Action:
            - "xray:PutTraceSegments"
            - "xray:PutTelemetryRecords"
          Resource:
            - "*" 

functions:
  fileProcess:
    handler: index.handler
    events:
       - sqs: 
          arn: arn:aws:sqs:ap-east-1:432797229265:file-process
          batchSize: 1
          functionResponseType: ReportBatchItemFailures
          maximumConcurrency: 20
    environment: ${file(env.${opt:stage, 'sit'}.yml)}
    timeout: 900  
plugins:
  # - serverless-plugin-include-dependencies
  # Bundling the javascript / typescript
  - serverless-esbuild
```
{% endcode %}
