✨
FastAPIでswagger-uiを表示する
前回
今回やりたいこと
前回作ったSAMを使ったHelloWorldをベースにFastAPI、MangumからAPIドキュメント(swagger-ui)を作る
環境整備
■pip install
install
pip install fastapi
pip install mangum
pip install uvicorn
hello_worldを書き換え
■app.py
~/environment/sam-app-1/hello_world/app.py
を以下内容で書き換え
from fastapi import FastAPI
from mangum import Mangum
app = FastAPI()
@app.get("/hello")
def root():
return {"message": "Hello World1"}
lambda_handler = Mangum(app)
■requirements.txt
~/environment/sam-app-1/hello_world/requirements.txt
を以下内容で書き換え
requests
fastapi
mangum
template.yamlを書き換え
■template.yaml
~/environment/sam-app-1/template.yaml
を以下内容で書き換え
変更点はタイムアウトを10sに変更・追加したのみ
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
sam-app
Sample SAM Template for sam-app
# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
Function:
Timeout: 10
MemorySize: 128
Resources:
HelloWorldFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: hello_world/
Handler: app.lambda_handler
Runtime: python3.9
Timeout: 10
Architectures:
- x86_64
Events:
HelloWorld:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /hello
Method: get
Outputs:
# ServerlessRestApi is an implicit API created out of Events key under Serverless::Function
# Find out more about other implicit resources you can reference within SAM
# https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api
HelloWorldApi:
Description: "API Gateway endpoint URL for Prod stage for Hello World function"
Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/"
HelloWorldFunction:
Description: "Hello World Lambda Function ARN"
Value: !GetAtt HelloWorldFunction.Arn
HelloWorldFunctionIamRole:
Description: "Implicit IAM Role created for Hello World function"
Value: !GetAtt HelloWorldFunctionRole.Arn
build、invoke、deploy
■sam build
実行
cd ~/environment/sam-app-1/
sam build
結果
sam build
Building codeuri: /home/ec2-user/environment/sam-app-1/hello_world runtime: python3.9 metadata: {} architecture: x86_64 functions: HelloWorldFunction
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
■sam local invoke
FastAPI、Mangumを咬ましたので直接実行はエラーになります
sam local invoke
Invoking app.lambda_handler (python3.9)
Skip pulling image and use local one: public.ecr.aws/sam/emulation-python3.9:rapid-1.70.0-x86_64.
Mounting /home/ec2-user/environment/sam-app-1/.aws-sam/build/HelloWorldFunction as /var/task:ro,delegated inside runtime container
START RequestId: 68a95560-863c-40ee-b1ae-da964146a58a Version: $LATEST
[ERROR] RuntimeError: The adapter was unable to infer a handler to use for the event. This is likely related to how the Lambda function was invoked. (A raise RuntimeError( # pragma: no cover68, in inferl__alid for a supported handler.)
END RequestId: 68a95560-863c-40ee-b1ae-da964146a58a
REPORT RequestId: 68a95560-863c-40ee-b1ae-da964146a58a Init Duration: 0.05 ms Duration: 745.57 ms Billed Duration: 746 ms Memory Size: 128 MB Max Memory Used: 128 MB
{"errorMessage": "The adapter was unable to infer a handler to use for the event. This is likely related to how the Lambda function was invoked. (Are you testing locally? Make sure the request payload is valid for a supported handler.)", "errorType": "RuntimeError", "requestId": "68a95560-863c-40ee-b1ae-da964146a58a", "stackTrace": [" File \"/var/task/mangum/adapter.py\", line 76, in __call__\n handler = self.infer(event, context)\n", " File \"/var/task/mangum/adapter.py\", line 68, in infer\n raise RuntimeError( # pragma: no cover\n"]}
■sam local start-api
実行
sam local start-api
別ターミナルでAPI CALL
curl http://127.0.0.1:3000/hello
結果
Mounting HelloWorldFunction at http://127.0.0.1:3000/hello [GET]
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. If you used sam build before running local commands, you will need to re-run sam build for the changes to be picked up. You only need to restart SAM CLI if you update your AWS SAM template
2023-01-16 13:08:05 * Running on http://127.0.0.1:3000/ (Press CTRL+C to quit)
Invoking app.lambda_handler (python3.9)
Skip pulling image and use local one: public.ecr.aws/sam/emulation-python3.9:rapid-1.70.0-x86_64.
Mounting /home/ec2-user/environment/sam-app-1/.aws-sam/build/HelloWorldFunction as /var/task:ro,delegated inside runtime container
START RequestId: 795ee2be-9cc3-4a36-91c7-bcd300492028 Version: $LATEST
END RequestId: 795ee2be-9cc3-4a36-91c7-bcd300492028
REPORT RequestId: 795ee2be-9cc3-4a36-91c7-bcd300492028 Init Duration: 0.20 ms Duration: 569.09 ms Billed Duration: 570 ms Memory Size: 128 MB Max Memory Used: 128 MB
2023-01-16 13:08:58 127.0.0.1 - - [16/Jan/2023 13:08:58] "GET /hello HTTP/1.1" 200 -
別ターミナルの結果
{"message":"Hello World"}
■sam deploy
実行
sam deploy
結果
sam deploy
Uploading to sam-app-1/cab4ea6d13ce8e849c25c66b3dda7c2d 4038327 / 4038327 (100.00%)
Deploying with following values
===============================
Stack name : sam-app-1
Region : ap-northeast-1
Confirm changeset : False
Disable rollback : False
Deployment s3 bucket : aws-sam-cli-managed-default-samclisourcebucket-1hsg213hvqm87
Capabilities : ["CAPABILITY_IAM"]
Parameter overrides : {}
Signing Profiles : {}
Initiating deployment
=====================
Uploading to sam-app-1/b4b8766f3a8a434d20ab4f15f37a8f7c.template 1221 / 1221 (100.00%)
Waiting for changeset to be created..
CloudFormation stack changeset
-------------------------------------------------------------------------------------------------------------------------------------------------
Operation LogicalResourceId ResourceType Replacement
-------------------------------------------------------------------------------------------------------------------------------------------------
* Modify HelloWorldFunction AWS::Lambda::Function False
* Modify ServerlessRestApi AWS::ApiGateway::RestApi False
-------------------------------------------------------------------------------------------------------------------------------------------------
Changeset created successfully. arn:aws:cloudformation:ap-northeast-1:123456789012:changeSet/samcli-deploy1673874665/3b354b55-5629-479d-9445-ff2ece1ea14c
2023-01-16 13:11:16 - Waiting for stack create/update to complete
CloudFormation events from stack operations (refresh every 0.5 seconds)
-------------------------------------------------------------------------------------------------------------------------------------------------
ResourceStatus ResourceType LogicalResourceId ResourceStatusReason
-------------------------------------------------------------------------------------------------------------------------------------------------
UPDATE_IN_PROGRESS AWS::Lambda::Function HelloWorldFunction -
UPDATE_COMPLETE AWS::Lambda::Function HelloWorldFunction -
UPDATE_COMPLETE_CLEANUP_IN_PROGRES AWS::CloudFormation::Stack sam-app-1 -
S
UPDATE_COMPLETE AWS::CloudFormation::Stack sam-app-1 -
-------------------------------------------------------------------------------------------------------------------------------------------------
CloudFormation outputs from deployed stack
----------------------------------------------------------------------------------------------------------------------------------------------------
Outputs
----------------------------------------------------------------------------------------------------------------------------------------------------
Key HelloWorldFunctionIamRole
Description Implicit IAM Role created for Hello World function
Value arn:aws:iam::123456789012:role/sam-app-1-HelloWorldFunctionRole-1XQBL5UFOATLL
Key HelloWorldApi
Description API Gateway endpoint URL for Prod stage for Hello World function
Value https://xxx.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/
Key HelloWorldFunction
Description Hello World Lambda Function ARN
Value arn:aws:lambda:ap-northeast-1:123456789012:function:sam-app-1-HelloWorldFunction-5dZOxwSuoqyf
----------------------------------------------------------------------------------------------------------------------------------------------------
Successfully created/updated stack - sam-app-1 in ap-northeast-1
API Call
curl https://xxx.execute-api.ap-northeast-1.amazonaws.com/Prod/hello
API Call結果
{"message":"Hello World"}
uvicornの実行
■uvicornの実行
実行
cd ~/environment/sam-app-1/hello_world/
uvicorn app:app --reload
結果
INFO: Will watch for changes in these directories: ['/home/ec2-user/environment/sam-app-1/hello_world']
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO: Started reloader process [23249] using StatReload
INFO: Started server process [23280]
INFO: Waiting for application startup.
INFO: Application startup complete.
■uvicornの実行
uvicornがデフォでは8000portを利用しますが、Cloud9の仕様に合わせるため8080portを指定します
実行
uvicorn app:app --reload --port 8080
swagger-ui
Cloud9 Header -> Preview -> Preview Running Application
で画面表示後、Pathに/docsを指定します
swagger-uiでAPI Callも可能です。
参考
■fastapi
■mangum
Discussion