使用Serverless Requirements在AWS无服务器架构中配置Python依赖库

最近一直在尝试AWS Serverless(无服务器架构)的系列产品,比如:S3, Lambda, APIGateway等等。在使用Serverless这个框架编写Lambda的时候经常会遇到一个问题就是:在Python中要使用其他依赖库怎么办?本来Lambda就是AWS微服务架构中的最小单元了,那么如何导入这些依赖库呢?其中的一个方案就是使用Serverless Requirements这个插件来管理这些依赖库。下面以一个简单的例子进行说明。

当然,前提是已经安装了serverless,如未安装,请先行安装,整个安装过程非常简单。安装完毕后创建一个项目:

serverless create --template aws-python3 --name dependency-test --path dependency-test
cd dependency-test

进入”dependency-test”目录后可以看到共生成了两个文件:handler.py和serverless.yml。

先来看看handler.py这个文件,将注释删除后可以看到整个代码非常简单:

import json

def hello(event, context):
    body = {
        "message": "Go Serverless v1.0! Your function executed successfully!",
        "input": event
    }

    response = {
        "statusCode": 200,
        "body": json.dumps(body)
    }

    return response

下面我们以numpy这个最为常见的依赖库为例来进行说明。将handler.py修改成如下这样:

import json
import numpy as np

def hello(event, context):
    a = np.arange(9).reshape(3, 3)

    body = {
        "array": str(a)
    }

    response = {
        "statusCode": 200,
        "body": json.dumps(body)
    }

    return response

if __name__ == "__main__":
    print(hello('', ''))

其实在Lambda中,完全不用添加最后两行,这里只是为了在本地测试的。运行:

python handler.py

可以看到如下结果:

{'statusCode': 200, 'body': '{"array": "[[0 1 2]\\n [3 4 5]\\n [6 7 8]]"}'}

接下来需要将其部署到AWS,首先初始化当前目录,并安装依赖库:

npm install --save serverless-python-requirements

这样就会生成package-lock.json以及node_modules目录。是不是有些奇怪?Python的代码下出现了Node.js的文件和库。其实这也没什么奇怪的。因为Serverless这个框架就是用Node.js实现的,其插件”serverless-python-requirements”也是用Node.js实现的,自然就需要node_modules了。

为了能让”serverless-python-requirements”正常工作,需要添加requirements.txt这个文件,其内容为:

numpy==1.18.3

然后修改默认的serverless.yml,添加对serverless-python-requirements这个插件的引用:

service: dependency-test

provider:
  name: aws
  runtime: python3.8

functions:
  hello:
    handler: handler.hello
    events:
      - http:
          path: dependency_test
          method: get

plugins:
  - serverless-python-requirements

custom:
  pythonRequirements:
    dockerizePip: true

部署到AWS

serverless deploy

可以看到已经成功部署:

Serverless

测试一下:

Serverless