简体   繁体   English

Python 中的 AWS Lambda:在 Lambda 函数处理程序中导入父包/目录

[英]AWS Lambda in Python: Import parent package/directory in Lambda function handler

I have a directory structure like the following in my serverless application(simplest app to avoid clutter) which I created using AWS SAM with Python 3.8 as the runtime:我在我的无服务器应用程序(避免混乱的最简单应用程序)中有一个类似于以下的目录结构,我使用 AWS SAM 和 Python 3.8 作为运行时创建了它:

├── common
│   └── a.py
├── hello_world
│   ├── __init__.py
│   ├── app.py
│   └── requirements.txt
└── template.yaml

I would like to import common/a.py module inside the Lambda handler - hello_world/app.py .我想在 Lambda 处理程序中导入common/a.py模块 - hello_world/app.py Now I know that I can import it normally in Python by adding the path to PYTHONPATH or sys.path , but it doesn't work when the code is run in Lambda inside a Docker container.现在我知道我可以通过将路径添加到PYTHONPATHsys.path 在 Python 中正常导入它,但是当代码在 Docker 容器内的 Lambda 中运行时它不起作用。 When invoked, the Lambda handler function is run inside /var/task directory and the folder structure is not regarded.调用时,Lambda 处理函数在/var/task目录中运行,不考虑文件夹结构。

I tried inserting /var/task/common , /var/common , /var and even /common to sys.path programmatically like this:我尝试以编程方式将/var/task/common/var/common/var甚至/common插入到sys.path如下所示:

import sys
sys.path.insert(0, '/var/task/common')
from common.a import Alpha

but I still get the error:但我仍然收到错误:

ModuleNotFoundError: No module named 'common'

I am aware of Lambda Layers but given my scenario, I would like to directly reference the common code in multiple Lambda functions without the need of uploading to a layer.我知道Lambda 层,但鉴于我的场景,我想直接引用多个 Lambda 函数中的公共代码,而无需上传到层。 I want to have something like the serverless-python-requirements plugin in the Serverless framework but in AWS SAM.我想在无服务器框架中但在 AWS SAM 中有类似serverless-python-requirements插件的东西。

So my question is, how should I add this path to common to PYTHONPATH or sys.path ?所以我的问题是,我应该如何将此路径添加到PYTHONPATHsys.path common中? Or is there an alternative workaround for this like [serverless-python-requirements][3] to directly import a module in a parent folder without using Lambda Layers?或者是否有替代解决方法,例如[serverless-python-requirements][3]直接在父文件夹中导入模块而不使用 Lambda 层?

I was having a similar issue with package dependencies and according to AWS Knowledge Center you should put all of your items at the root level:我在包依赖项方面遇到了类似的问题,根据 AWS 知识中心的说法,您应该将所有项目放在根级别:

You might need to create a deployment package that includes the function modules located in the root of the .zip file with read and execute permissions for all files.您可能需要创建一个部署包,其中包含位于 .zip 文件根目录中的功能模块,并对所有文件具有读取和执行权限。

According to https://aws.amazon.com/premiumsupport/knowledge-center/build-python-lambda-deployment-package/根据https://aws.amazon.com/premiumsupport/knowledge-center/build-python-lambda-deployment-package/

I didn't find what I was looking for but I ended up with a solution to create a single Lambda function in the root which handles all the different API calls within the function.我没有找到我要找的东西,但我最终找到了一个解决方案,可以在根目录中创建一个单独的 Lambda 函数,该函数处理函数内的所有不同 API 调用。 Yes my Lambda function is integrated with API Gateway, and I can get the API method and API path using event["httpMethod"] and event ["httpPath"] respectively.是的,我的 Lambda 函数与 API Gateway 集成,我可以分别使用event["httpMethod"]event ["httpPath"]获取 API 方法和 API 路径。 I can then put all the packages under the root and import them between each other.然后我可以将所有包放在根目录下并在彼此之间导入它们。

For example, say I have 2 API paths /items and /employees that need to be handled and both of them need to handle both GET and POST methods, the following code suffices:例如,假设我有 2 个 API 路径/items/employees需要处理,并且它们都需要处理 GET 和 POST 方法,以下代码就足够了:

if event["path"] == '/items':
   if event["httpMethod"] == 'GET':
      ...
   elif event["httpMethod"] == 'POST':
      ...
elif event["path"] == '/employees':
   if event["httpMethod"] == 'GET':
      ...
   if event["httpMethod"] == 'POST':
      ...

So now I can have as much packages under this Lambda function.所以现在我可以在这个 Lambda 函数下拥有尽可能多的包。 For example, the following is how repository looks like now:例如,以下是存储库现在的样子:

├── application
│   └── *.py
├── persistence
│   └── *.py
├── models
│   └── *.py
└── rootLambdaFunction.py
└── requirements.txt

This way, I can import packages at will wherever I want within the given structure.这样,我可以在给定结构中的任何地方随意导入包。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM