Search code examples
pythonflaskaws-lambdaserverless-framework

Serverless wsgi error on lambda but working fine on local


Hey guys I have some problem with flask + serverless-wsgi and serverless-python-requirements plugins when I deploy on lambda and test this function on AWS console and I got this error below.

Don't know why It's work on local test.

Response
{
  "errorMessage": "'headers'",
  "errorType": "KeyError",
  "stackTrace": [
    "  File \"/var/task/wsgi_handler.py\", line 110, in handler\n    return serverless_wsgi.handle_request(wsgi_app, event, context)\n",
    "  File \"/var/task/serverless_wsgi.py\", line 170, in handle_request\n    return handle_lambda_integration(app, event, context)\n",
    "  File \"/var/task/serverless_wsgi.py\", line 308, in handle_lambda_integration\n    headers = Headers(event[u\"headers\"])\n"
  ]
}

Before I faced this issue I have founded no werkzeug module error so I downgraded my requirements.txt but It still not work.

flask==1.0.2
werkzeug==1.0.0

Here is my handler.py this function is just return something.

import os
import sys
import json
import logging
logger = logging.getLogger()
logger.setLevel(logging.INFO)
env = os.environ

from flask import Flask, request, Response

app = Flask(__name__)

@app.route('/toro',methods = ['POST'])
def toro():
    data = {
                'name': 'Toro'
    }

    js = json.dumps(data)

    response = Response(js, status=200, mimetype='application/json')
            
    return response




    
    
     

And this my serverless.yml

service: my-service

plugins:
  - serverless-aws-documentation
  - serverless-s3-deploy
  - serverless-domain-manager
  - serverless-plugin-warmup
  - serverless-offline
  - serverless-wsgi
  - serverless-python-requirements

provider:
  name: aws
  runtime: python3.7
  stage: dev
  region: ap-southeast-1
  versionFunctions: false
  profile: default
  memorySize: 1024
  timeout: 30
  logRetentionInDays: 14
  logs:
    restApi: true
  environment:
    NODE_ENV: ${self:provider.stage} 

  vpc:
    securityGroupIds:
      - sg-xxxxxxxxxxxxx
    subnetIds:
      - subnet-xxxxxxxxxxx
  iamRoleStatements:
    - Effect: "Allow"
      Action:
        - "secretsmanager:GetSecretValue"
      Resource:
        - "*"
    - Effect: "Allow"
      Action:
        - "s3:PutObject"
        - "s3:PutObjectAcl"
        - "s3:GetObject"
        - "s3:ListBucket"
        - "s3:DeleteObject"
      Resource:
        - "*"
    - Effect: "Allow"
      Action:
        - "logs:CreateLogGroup"
        - "logs:CreateLogStream"
        - "logs:PutLogEvents"
        - "ec2:CreateNetworkInterface"
        - "ec2:DescribeNetworkInterfaces"
        - "ec2:DeleteNetworkInterface"
        - "ec2:AssignPrivateIpAddresses"
        - "ec2:UnassignPrivateIpAddresses"
      Resource:
        - "*"
    - Effect: "Allow"
      Action:
        - "elasticfilesystem:ClientMount"
        - "elasticfilesystem:ClientRootAccess"
        - "elasticfilesystem:ClientWrite"
        - "elasticfilesystem:DescribeMountTargets"
      Resource:
        - "*"
        
functions:
  toro:
    handler: wsgi_handler.handler
    reservedConcurrency: 10
    events:
      - http:
          path: /toro
          method: post
          cors:
            origin: "*"
        
custom:
  wsgi:
    app: handler.app
    packRequirements: false
  pythonRequirements:
    dockerizePip: 'non-linux'

Is here have somebody who can help me please.


Solution

  • You must also pass the headers prop. If you use the app Postman to make the request, it will automatically pass that header prop. Otherwise, you'll have to explicitly pass it.

    Here's an example valid json you could pass

    {
      "requestPath": "",
      "headers": {},
      "body": {
        "username": "some_username",
        "password": "p@ssW0rD"
      }
    }