14
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

FastAPI を Azure Functions Python Programming Model v2 で動かしてみる

Last updated at Posted at 2023-06-27

本記事について

Microsoft Build 2023 で Azure FunctionsPython Programming Model v2 が GA (一般提供) となりました。本記事では、この Python Programming Model v2 を利用して、FastAPI で作られた Web API を Azure Functions 上にホストする方法を見ていきます。

Python Programming Model v2 の特徴

Python Programming Model v2 の特徴は以下になります。

  • 単純化されたフォルダー構造。Function App 内のファイルの数が少なくなります。アプリケーション内の複数の関数を同じファイルで定義できるようになりました。

  • トリガーとバインディングはデコレーターとして表されるため、function.json という構成ファイルが必要なくなります。

  • ブループリント機能のインポートを使った合理化されたワークフロー。ブループリントは、アプリケーション内の機能の論理的なグループ化も促進します。

  • VS Code の新しい「テンプレートの表示」オプションを使用すると、ドキュメントに簡単にアクセスできるようになります。

VS Code でコードを作成

ここから、VS Code でコードのひな型を作成し、それを変更していきます。

コマンドパレットから Function App を作成

VS Code でコマンドパレットを開き、Azure Functions: Create Function... を選択します。言語で、Python (Programming Model V2) を選びます。

image.png

image.png

FastAPI の Hello World コードを追加

V2 では function.json がなくなったため、Python のファイルにコードを追加するだけでよくなりました。今回のフォルダ構成は下記になります。

フォルダ構造
<project_root>/
 | - .venv/
 | - .vscode/
 | - function_app.py
 | - routers
 | | - __init__.py
 | | - hello.py
 | - .funcignore
 | - host.json
 | - local.settings.json
 | - requirements.txt

実行する Python コードは下記のファイルを用意しました。

function_app.py
#function_app.py

import azure.functions as func 
from fastapi import FastAPI
from routers import hello

fast_app = FastAPI() 
fast_app.include_router(hello.router)

@fast_app.get("/")
async def root():
    return {"message":"Hello world"}

app = func.AsgiFunctionApp(app=fast_app, http_auth_level=func.AuthLevel.FUNCTION)
routers/hello.py
# hello.py

from fastapi import APIRouter

router = APIRouter()

@router.get("/hello/{name}", tags=["hello"])
async def hello_name(name: str):
    return {"message": f"Hello {name}"}

@router.get("/hello", tags=["hello"])
async def hello(name: str = ""):
    return {"message": f"Hello {name}"}
requirements.txt
azure-functions
fastapi

Azure Functions Python Programming Model v2 における FastAPI の実行ならではのところとしては、下記の部分になります。

app = func.AsgiFunctionApp(app=fast_app, http_auth_level=func.AuthLevel.FUNCTION)

また、host.json のファイルは下記のようにします。

host.json
{
  "version": "2.0",
  "logging": {
    "applicationInsights": {
      "samplingSettings": {
        "isEnabled": true,
        "excludedTypes": "Request"
      }
    }
  },
  "extensionBundle": {
    "id": "Microsoft.Azure.Functions.ExtensionBundle",
    "version": "[4.*, 5.0.0)"
  },
  "extensions": {
    "http": {
      "routePrefix": ""
    }
  }
}

Fast API や Flask を Azure Functions の HTTP トリガーを使う関数としてホストする場合、httproutePrefix が Extension の設定が必要になります。

公式ドキュメントとしては下記をご参照ください。

Azure Functions にデプロイ

Azure Portal で関数アプリを作成します。

image.png

そして、VS Code からデプロイしてみます。

image.png

関数アプリにアクセスすると下記のように表示されました。

image.png

(補足) Application Insights について

Azure Functions では、組み込みで Azure の APM である、Application Insights を有効化することができます。ただし、FastAPI をホストする場合、トレーシングを行うには手動でコードに数行インストルメンターを組み込む必要があります。

  • Python の利用モジュール
requirements.txt
opentelemetry-instrumentation-fastapi
azure-monitor-opentelemetry
  • Python コード
function_app.py
from azure.monitor.opentelemetry import configure_azure_monitor
from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor

configure_azure_monitor(
    connection_string="<Application Insights の接続文字列>",
)
FastAPIInstrumentor.instrument_app(fast_app)

これにより下記のようにトレーシングを行えます。(下記のスクリーンショットは、上記の hello.py を修正し、リクエスト内容を Cosmos DB に記録するようにした関数のものです。)

image.png

image.png

Application Insights による Python アプリについては、下記もご参照ください。

最後に

*本稿は、個人の見解に基づいた内容であり、所属する会社の公式見解ではありません。また、いかなる保証を与えるものでもありません。正式な情報は、各製品の販売元にご確認ください。

14
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?