KeyError:“ requestContext”,FastAPI,Mangum,无服务器

问题描述

我正在尝试使用无服务器框架来部署Python Fast API WebApp。 与问题有关:

https://github.com/jordaneremieff/mangum/issues/126

当我使用无服务器部署它时,sls depoy并调用函数时,出现以下错误

[ERROR] KeyError: 'requestContext'
Traceback (most recent call last):
  File "/var/task/mangum/adapter.py",line 110,in __call__
    return self.handler(event,context)
  File "/var/task/mangum/adapter.py",line 130,in handler
    if "eventType" in event["requestContext"]:

我尝试使用python 3.8和3.7。 无法在网上找到相同的分辨率。 还尝试使用参数spec_version = 2(我感觉不是必需的)。

我觉得这里缺少东西,问题出在附近:

Adapter requires the @R_147_4045@ion in the event and request context to form the Asgi connection scope.

想知道是否有人使用无服务器框架在AWS Lambda上使用FastAPI。

我的处理程序:

from fastapi import FastAPI
from mangum import Mangum


app = FastAPI()
handler = Mangum(app)

@app.get("/ping")
def ping():
    return {'response': 'pong'}

serverless.yml:

provider:
  name: aws
  runtime: python3.8
  stage: dev
  region: ap-southeast-1
  memorySize: 256

functions:
  ping:
    handler: ping.handler
    events:
      - http:
          path: ping
          method: get
          cors: true

我的要求。txt

appnope==0.1.0
backcall==0.2.0
certifi==2020.6.20
chardet==3.0.4
click==7.1.2
decorator==4.4.2
fastapi==0.61.1
h11==0.9.0
httpcore==0.10.2
httptools==0.1.1
httpx==0.14.1
idna==2.10
ipython==7.17.0
ipython-genutils==0.2.0
jedi==0.17.2
mangum==0.9.2
parso==0.7.1
pexpect==4.8.0
pickleshare==0.7.5
prompt-toolkit==3.0.6
ptyprocess==0.6.0
pydantic==1.6.1
Pygments==2.6.1
requests==2.24.0
rfc3986==1.4.0
six==1.15.0
sniffio==1.1.0
starlette==0.13.6
traitlets==4.3.3
typing-extensions==3.7.4.2
urllib3==1.25.10
uvicorn==0.11.8
uvloop==0.14.0
wcwidth==0.2.5
websockets==8.1

解决方法

问题出在mangum适配器之内,期望输入类似于AWS API Gateway shown here指定的event内容。您会看到其中有一个requestResponse字典,Mangum适配器似乎严格要求该字典起作用。如果您的AWS Lambda事件不包含该键,那么您需要添加一个占位符字段或构造一个新的上下文字典以供其查找。

这可以通过创建自定义处理程序as shown within this part of the Mangum docs来完成。如果您不特别关心适配器将上下文理解为什么,那么可以使用以下版本:

def handler(event,context):
    event['requestContext'] = {}  # Adds a dummy field; mangum will process this fine
    
    asgi_handler = Mangum(app)
    response = asgi_handler(event,context)

    return response