AWS SAM CLIを使用してFast APIをローカルでテストする(Windows10)

スポンサーリンク

SAM CLIを使用してFast APIをローカルでテストしてみます。

■PC環境

>Windows 10

>sam –version
SAM CLI, version 1.52.0

>docker –version
Docker version 20.10.12, build e91ed57

>Python バージョン
Python 3.8.5

■アプリケーションのディレクトリを作成する

SAM CLIを使用してFast APIをローカルでテストしていきますので、まずはアプリケーションのディレクトリを作成します。

今回は「C:\Users\user_(フォルダパス)」内に「fastapi-on-lambda」というディレクトリを作成しました。

■FastAPIアプリケーションを作成する

ディレクトリを作成後、簡単なFastAPIアプリケーションを作成していきます。

■コード

from fastapi import FastAPI
from mangum import Mangum

app = FastAPI()

@app.get("/")
def get_root():
    return {"message":"hello hello cq"}

handler = Mangum(app)

今回は、LambdaのイベントペイロードとFastAPIの間のギャップを埋めるために、mangumと呼ばれるライブラリを使用します。このライブラリは、AWS API Gatewayから呼び出されるLambda内で動作するASGIアプリケーションのアダプタとして動作するものです。

このコードを「__init__.py」という名前で保存します。保存先は今回作成した「fastapi-on-lambda」というディレクトリ内に「src」というディレクトリを作り、さらに「app」というディレクトリを作り、この中が保存先となります。

■実行時の依存関係を指定する

保存後、関数を実行するためには、サードパーティの依存関係をいくつかインストールする必要がありますので、「requirements.txt」というファイルを作成します。

■requirements.txt

fastapi
mangum

「requirements.txt」には、上記の2つの依存関係を記述し、保存します。なお、このファイルの保存先は、今回作成した「fastapi-on-lambda」というディレクトリ内の「src」が保存先となります。

■SAMテンプレートを作成する

保存後、今回はFast APIをローカルでテストするだけですが、AWS SAM CLIを使用してアプリケーションをデプロイすることも考え、リソースを定義するためにyaml形式でSAM templateを作成します。

■コード

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: FastAPI on Lambda

Resources:
  Function:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: "FastAPILambda"
      CodeUri: src
      Handler: app.handler
      Runtime: python3.8
      Events:
        Api:
          Type: HttpApi
          Properties:
            ApiId: !Ref Api

  Api:
    Type: AWS::Serverless::HttpApi

Outputs:
  ApiUrl:
    Description: URL of your API
    Value:
      Fn::Sub: 'https://${Api}.execute-api.${AWS::Region}.${AWS::URLSuffix}/'

SAM templateの書き方や作成についてはこちら(https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-specification-template-anatomy.html)が参考になります。なお、今回のtemplate(https://dev.to/aws-builders/deploy-fastapi-on-aws-part-1-lambda-api-gateway-1cp0)はこちらを参考していますが、修正を加えてあります。

修正としては「Resources:」の「Runtime: python3.8」と修正。python3.9でbuildすると、下記のようにbuildが失敗する。

Building codeuri: C:\Users\user_\fastapi-on-lambda\src runtime: python3.9 metadata: {} architecture: x86_64 functions: ['Function']

Build Failed
Error: PythonPipBuilder:Validation - Binary validation failed for python, searched for python in following locations  : ['C:\\Program Files (x86)\\Python37-32\\python.EXE', 'C:\\Program Files\\Python36\\python.EXE', 'C:\\Program Files\\Python38\\python.EXE', 'C:\\Users\\user_\\AppData\\Local\\Microsoft\\WindowsApps\\python.EXE'] which did not satisfy constraints for runtime: python3.9. Do you have python for runtime: python3.9 on your PATH?

失敗したので、今回のWindows10にインストールされている「python3.8」に変更しています。

さらに「Resources:」に「Timeout: 10」を追加しています。Lambda関数のデフォルトのタイムアウトは3秒(https://stackoverflow.com/questions/56182205/aws-lambda-function-timedout-after-3-sec-using-aws-sam)なので、今回はタイムアウトを「10」としています。これを追加せずに、buildを行い、ローカルでテストすると、下記のようにテストが失敗する。

Mounting Function at http://127.0.0.1:3000$default [X-AMAZON-APIGATEWAY-ANY-METHOD]
You can now browse to the above endpoints to invoke your functions. You do not need to restart/reload SAM CLI while working on your functions, changes will be reflected instantly/automatically. You only need to restart SAM CLI if you update your AWS SAM template
2022-06-24 15:09:34  * Running on http://127.0.0.1:3000/ (Press CTRL+C to quit)
Invoking app.handler (python3.8)
Skip pulling image and use local one: public.ecr.aws/sam/emulation-python3.8:rapid-1.52.0-x86_64.

Mounting C:\Users\user_\fastapi-on-lambda\.aws-sam\build\Function as /var/task:ro,delegated inside runtime container
START RequestId: 9d3d38ed-1fea-46b1-b563-fd72fc4df540 Version: $LATEST
Function 'Function' timed out after 3 seconds
No response from invoke container for Function
Invalid lambda response received: Lambda response must be valid json
2022-06-24 15:09:49 127.0.0.1 - - [24/Jun/2022 15:09:49] "GET / HTTP/1.1" 502 -

「No response from invoke container for Function」といったメッセージが出力され、またAPIが「{“message”:”Internal Server Error”}」を返してしまう。

これらの修正を加えて、「template.yaml」という名前で保存します。なお、保存先は「fastapi-on-lambda」ディレクトリが保存先となります。

■SAM CLIを使用してAPIをローカルでテストする

保存後、SAM CLI を使用してAPIをローカルでテストできるように、FastAPIアプリケーションをbuildします。buildのために、Windows10のコマンドプロンプトを起動します。

>cd fastapi-on-lambda

起動後、上記のコマンドを入力し、Enterキーを押します。cdコマンドで「fastapi-on-lambda」ディレクトリに移動します。

>sam build

移動後、上記のコマンドを入力し、Enterキーを押します。FastAPIアプリケーションをbuildします。

Building codeuri: C:\Users\user_\fastapi-on-lambda\src runtime: python3.8 metadata: {} architecture: x86_64 functions: ['Function']
Running PythonPipBuilder:ResolveDependencies
Running PythonPipBuilder:CopySource

Build Succeeded

Built Artifacts  : .aws-sam\build
Built Template   : .aws-sam\build\template.yaml

Commands you can use next
=========================
[*] Validate SAM template: sam validate
[*] Invoke Function: sam local invoke
[*] Test Function in the Cloud: sam sync --stack-name {stack-name} --watch
[*] Deploy: sam deploy --guided

Enterキーを押すと、「Build Succeeded」といったメッセージが出力されます。これでbuildが完了となります。

>sam local start-api

FastAPIアプリケーションの構築完了後、APIをローカルで開始します。開始するために、上記のコマンドを入力し、Enterキーを押します。

Mounting Function at http://127.0.0.1:3000$default [X-AMAZON-APIGATEWAY-ANY-METHOD]
You can now browse to the above endpoints to invoke your functions. You do not need to restart/reload SAM CLI while working on your functions, changes will be reflected instantly/automatically. You only need to restart SAM CLI if you update your AWS SAM template
2022-06-25 11:53:50  * Running on http://127.0.0.1:3000/ (Press CTRL+C to quit)

Enterキーを押すと、上記のメッセージが出力されます。「Running on http://127.0.0.1:3000/」と出力されていますので、「http://127.0.0.1:3000/」のURLをコピーします。

>curl http://127.0.0.1:3000

コピー後、新しくコマンドプロンプトを起動します。起動後、上記のコマンドを入力し、Enterキーを押します。Windows10でcurlが標準で利用できるようになっているので、これを利用しテストします。

{"message":"hello hello cq"}

Enterキーを押すと、今回作成したFastAPIアプリケーションでreturnとして返されるメッセージが出力されました。これでテストは成功となります。

Mounting Function at http://127.0.0.1:3000$default [X-AMAZON-APIGATEWAY-ANY-METHOD]
You can now browse to the above endpoints to invoke your functions. You do not need to restart/reload SAM CLI while working on your functions, changes will be reflected instantly/automatically. You only need to restart SAM CLI if you update your AWS SAM template
2022-06-25 11:53:50  * Running on http://127.0.0.1:3000/ (Press CTRL+C to quit)
Invoking app.handler (python3.8)
Skip pulling image and use local one: public.ecr.aws/sam/emulation-python3.8:rapid-1.52.0-x86_64.

Mounting C:\Users\user_\fastapi-on-lambda\.aws-sam\build\Function as /var/task:ro,delegated inside runtime container
START RequestId: 4c40f8a5-ded7-41e7-a9cf-97ad5496d802 Version: $LATEST
END RequestId: 4c40f8a5-ded7-41e7-a9cf-97ad5496d802
REPORT RequestId: 4c40f8a5-ded7-41e7-a9cf-97ad5496d802  Init Duration: 0.12 ms  Duration: 3719.03 ms    Billed Duration: 3720 ms        Memory Size: 128 MB     Max Memory Used: 128 MB
2022-06-25 11:57:29 127.0.0.1 - - [25/Jun/2022 11:57:29] "GET / HTTP/1.1" 200 -

なお、「sam local start-api」でローカルHTTPサーバーを作成した方には、上記のようなメッセージが出力されていることが確認できました。

コメント

タイトルとURLをコピーしました