Serverless framework with python and aws lambda

Question:

When i import a function from another file and do the deploy it doesn’t work.
It gives me: error 500 internal server error. The python requirements works fine, because the hello function doesn’t give me an error. But getPrediction doesn’t work well

In offline mode all works fine.

My handler.js

try:
    import unzip_requirements
except ImportError:
    pass

import json
import numpy
import scipy
from predictions.make_prediction import make_prediction

def hello(event, context):

    response = {"statusCode": 200, "body": {mod.__name__: mod.__version__ for mod in (numpy, scipy)}}
    return response 

def getPrediction(event, context):
    hola = make_prediction([1,2,3,4,5,6,7])
    response = {"statusCode": 200, "body": json.dumps(hola.tolist())}
    return response 

My serverless.yml

service: enno-searcher
frameworkVersion: '3'

provider:
  name: aws
  runtime: python3.7
  timeout: 29

plugins:
  - serverless-offline
  - serverless-python-requirements

package:
 patterns:
   - '!node_modules/**'
   - '!Lib/**'
   - '!README.md'
   - '!build/**'
   - '!__pycache__/**'
   - '!Include/**'

custom:
  pythonRequirements:
    dockerizePip: true
    zip: true

functions:
  hello:
    handler: handler.hello
    events:
      - httpApi:
          path: /
          method: get
  getPrediction:
    handler: handler.getPrediction
    events:
      - httpApi:
          path: /get-prediction
          method: get

I’ve tried changing the way I import external functions, but it keeps giving me the same error. maybe i’m doing it wrong

I have also tried not to import functions from other files. I’ve tried bringing the code from make_prediction to getPrediction, but it keeps giving me an error.

Asked By: Ismael Treviño

||

Answers:

I have managed to solve my problem with serverless framework. After many tests, this is how my files "handler.py" and my "serverless.yml" have stayed

serverless.yml

service: enno-searcher
frameworkVersion: '3'

provider:
  name: aws
  runtime: python3.7
  timeout: 29
  httpApi:
    cors: true

package:
  patterns:
   - '!node_modules/**'
   - '!Lib/**'
   - '!README.md'
   - '!build/**'
   - '!__pycache__/**'
   - '!Include/**'

functions:
  hello:
    handler: handler.hello
    events:
      - httpApi:
          path: /
          method: get
  test:
    handler: handler.test
    events:
      - httpApi:
          path: /test
          method: get
  getprediction:
    handler: handler.getPrediction
    events:
      - httpApi:
          path: /get-prediction
          method: get

plugins:
  - serverless-offline
  - serverless-python-requirements

custom:
  pythonRequirements:
    dockerizePip: non-linux
    zip: true

handler.py

try:
    import unzip_requirements
except ImportError:
    pass

import json

def hello(event, context):
    response = {
        "statusCode": 200,
        'headers': {
            'Access-Control-Allow-Origin': '*',
            "Access-Control-Allow-Credentials": True
        },
        "body": 'Searcher Backend v0.0.1'}
    return response

def test(event, context):
    from predictions.make_prediction import make_prediction
    hola = make_prediction([1,2,3,4,5,6,7])
    response = {
        "statusCode": 200,
        'headers': {
            'Access-Control-Allow-Origin': '*',
            "Access-Control-Allow-Credentials": True
        },
        "body": json.dumps(
        hola.tolist()
    )}
    return response 

def getPrediction(event, context):
    try:
        from predictions.make_prediction import make_prediction
        inputPrediction = event['queryStringParameters']['prediction']
        prediction = make_prediction(eval(inputPrediction))
        response = {
            "statusCode": 200,
            'headers': {
                'Access-Control-Allow-Origin': '*',
                "Access-Control-Allow-Credentials": True
            },
            "body": json.dumps(
            prediction.tolist()
        )}
        return response
    
    except KeyError as e:
        error_message = f'Faltan los parametros requeridos: {e}'
        response = {
            'statusCode': 400,
            'headers': {
                'Access-Control-Allow-Origin': '*',
                "Access-Control-Allow-Credentials": True
            },
            'body': json.dumps({'error': error_message})
        }
        return response
    
    except Exception as e:
        # Captura cualquier otra excepción y devuelve un mensaje de error genérico
        error_message = f'Se produjo un error al procesar la solicitud: {e}'
        response = {
            'statusCode': 500,
            'headers': {
                'Access-Control-Allow-Origin': '*',
                "Access-Control-Allow-Credentials": True
            },
            'body': json.dumps({'error': error_message})
        }
        return response

In this way, I have already managed to import functions from other documents. By importing it inside each function, I manage to contain the errors. I’ve also added try and except to further handle errors. I have also added cors to the APIs.

In addition, I have added many more functions (which I have not put here), with the same structure as the "getPrediction" function. They have all worked perfectly for me.

Answered By: Ismael Treviño