FastAPI環境構築

前回の投稿にてDjangoの置き替えとしてFastAPIの勉強を始めてかなり時間が経ってしまいましたが、まずはDjangoの時と同じようにシングルページWEBアプリケーションのテンプレートのような形で勉強しようと思い、同様にDockerの環境構築からの覚え書きです。

  • PythonイメージベースのDockerfile
    • nodejsをインストールして、モジュールとしてTypescript、Bootstrap、SASSを追加
    • Pythonライブラリとしてfastapi関連ライブラリをインストール
    • 実行ユーザーappを作成してsudo権限を与える
  • nginxプロキシを追加したdocker-compose.yml
    • /codeをマウントしてここにアプリを配置する
    • startupスクリプトを実行させる(環境変数設定とtypescript、sassコンパイラの常駐設定、APIサーバー:uvicornのデーモン起動)

上記プロジェクトを用いてdocker-compose up -dすると、サーバーが起動してブラウザからhttp://localhost:8080/でアクセス出来るようになります。

WEBアプリケーションの実体はapp/main.pyです。サンプルではある程度サンプルページが表示されるまで作り込んでしまっていますが、覚え書きとして一番単純なアプリケーションから

from fastapi import FastAPI

app = FastAPI()

@app.get('/')
async def index():
    return {'detail': 'Hello FastAPI World.'}

として、保存。ブラウザからhttp://localhost:8080/で読み込むと、

一番単純なFastAPIアプリ

こんな感じで表示されます。

app/main.pyの1行目でライブラリを読み込んで、アプリケーションインタンスの生成(3行目)、5行目はHTTPリクエストメソッドを表す関数デコレータです。例ではルートパスに対するGETリクエスト。その下のdefが関数定義で、名前は分かりやすければ何でも良いです。この関数の戻り値がHTTPのレスポンスとしてブラウザに返されます。

見て分かるように、このアプリケーションで返されるレスポンスはHTMLではないため、結果の見た目が変です。

FastAPIはDjangoと異なりAPIが主体なのでデフォルトではJSONで返すのが基本のようです。Ajaxなどでデータのやりとりをするのに向いている感じ。

HTTP通信を使用したアプリケーションでデータのやりとりを行い、クライアント側で見た目を準備するような用途ではこのままで良さそうですが、普通のWEBアプリのようにブラウザから利用したい場合はひと工夫が必要です。

少し調べた感じでは、二通りの方法があるようです。

  1. Jinja2Templatesテンプレートライブラリを利用する
    • FastAPIのもととなるStarletteやFlaskでも使用されており、Djangoのテンプレートと同様に変数埋込で動的なHTML文書を返すことが出来る。
  2. スタティックマウントしたディレクトリでhtmlを有効にする
    • from astapi.staticfiles import StaticFiles
    • app.mount(“/html”, StaticFiles(directory=”/code/html”, html=True))
    • 上記のように追加することで http://localhost:8080/html/ で/code/htmlに保存されたindex.htmlが表示されるのでそのページに仕込んだjavascriptからFastAPIのAPIを利用することで、シングルページアプリケーションを実現することが出来る。

サンプルでは1の方法を採用して、ルートページを表示させるようにしている。2の方法をにするには@app.get(‘/’)の部分を他のパスに変更するか、レスポンスごと削除し、スタティックマウント先を’/’ルートにすると良い。

サンプルのようにHTMLテンプレートを利用したレスポンスがこちら。

Bootstrapでチョッピリレイアウトしてみた。

最初は2の方法が良いなと思ってみたけど、サンプルにあるようにエラーベージをHTMLでちゃんと表示させるにはテンプレートを使用した方が便利だし、どうせテンプレート使うならルートページもテンプレートで行こう!という結論となりました。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

*

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)