LoginSignup
6
5

More than 1 year has passed since last update.

FastAPIとPythonの型ヒントが反映されたDocker環境を作ってそこにVS CodeのRemote Containerから接続する構築手順(2022年版)

Last updated at Posted at 2022-04-24

1. はじめに

FastAPIの開発環境をPythonの型付け(型ヒント)の恩恵を厳し目に受けながら開発したい。
そしてそれらの設定が反映されたDockerの開発環境をつくってホストの環境を汚さないようにしたい。
さらにVS CodeのRemote Containerを使うことでDockerの開発環境に接続して開発できる状態にしたい。

という動機から始まっています。

1-1.背景

上記を実現するためにFastAPIの環境構築について調査していると、「個人的にこの設定がスタンダートな最小構成だよね」をまとめるに苦労したのでこの際まとめておくことにしました。

以下が反映される最小構成を目指します。

  • Pythonで型付け(型ヒント)の恩恵をうける設定が入っていること
  • FastAPIの自動チューニングの設定が入っていること
  • 日本語化やタイムゾーンなどの基本的な設定がDockerイメージに含まれていること
  • これらをVS CodeのRemote Containerで開発できる設定になっていること

1-2. 前提条件

  • Remote ContainerはVS Codeにインストール済み
  • Docker Descktopはインストール済み
  • 今回はPython 3.9
    • FastAPIの公式イメージの最新版が執筆時点で3.9なので

2. 構築手順

とにかく動かしたい方は、以下の手順をコピペすれば動きます。

2-1. ディレクトリ構成

以下のように配置します。fastapi-testがworkspaceになるディレクトリです。

fastapi-test
├─ .devcontainer
    └─ devcontainer.json
├─ app
    └─ main.py
├─ .dockerignore
├─ Dockerfile
└─ requirements.txt

2-2. 各ファイルの内容

devcontainer.json

devcontainer.json はRemote Containerを使うときの設定ファイルです。
公式ドキュメントどおり .devcontainer/devcontainer.json に配置します。

VS CodeのRemote Containerを立ち上げたときに、以下の動作になるように設定しています。

  • Lintが動作すること
  • 型ヒントが厳しめに動作すること
  • ただし外部ライブラリについては余計な型チェックが入らないように動作すること
    • TypeScriptと違って型定義が提供されていないライブラリは多い
    • mypy.iniをおいても解決しないので diagnosticSeverityOverrides に設定を書くのがミソです

また、rootで作業できないように appuser でコンテナに接続するようにします。
後述のDockerfile内でappuserを作成しています。

{
	"name": "fastapi-test",
	"build": {
		"dockerfile": "../Dockerfile",
		"context": "..",
	},
    "runArgs": [ "--name", "fastapi-test"],
	"settings": { 
		"python.linting.enabled": true,
		"python.linting.pylintEnabled": true,
		"python.linting.pylintArgs": [
			"--disable", "E1101,E0213,R0201",
			"--extension-pkg-whitelist", "pydantic",
		],
		"python.linting.mypyEnabled": true,
		"python.analysis.typeCheckingMode": "strict",
		"python.analysis.diagnosticSeverityOverrides": {
			"reportMissingTypeStubs": "none",
			"reportUnknownParameterType": "none",
  			"reportUnknownMemberType": "none",
  			"reportUnknownArgumentType":  "none",
			"reportUnknownVariableType": "none"
		}
	},
	"extensions": [
		"ms-python.python",
        "njpwerner.autodocstring",
		"ms-python.vscode-pylance",
	],
	"postCreateCommand": "pip install -U mypy pylint",
	"remoteUser": "appuser"
}

main.py

公式ドキュメント の内容をそのまま拝借します。

from typing import Optional

from fastapi import FastAPI

app = FastAPI()


@app.get("/")
def read_root():
    return {"Hello": "World"}


@app.get("/items/{item_id}")
def read_item(item_id: int, q: Optional[str] = None):
    return {"item_id": item_id, "q": q}

.dockerignore

主にpython周りの余計なファイルなどがビルドに含まれないように設定しておきます

Dockerfile
README.md
*.pyc
*.pyo
*.pyd
__pycache__
.pytest_cache

Dockerfile

冒頭のとおり個人的にスタンダートな最小構成を書いています

# 公式のイメージ ちなみに80がEXPOSEされている
FROM tiangolo/uvicorn-gunicorn-fastapi:python3.9

# python周りの設定
# pycを生成しない、および 標準出力と標準エラー出力がすぐに出力されるようにする
ENV PYTHONDONTWRITEBYTECODE=1 PYTHONUNBUFFERED=1

# 日本語化周りの設定
RUN apt-get update && apt-get install -y locales && locale-gen ja_JP.UTF-8
ENV LANG=ja_JP.UTF-8 TZ=Asia/Tokyo

# お好みで
# RUN apt-get install -y vim less procps libssl-dev curl

# 専用のユーザーを作成してbashに変更する
RUN useradd --create-home appuser && chsh -s /bin/bash appuser
USER appuser
WORKDIR /home/appuser

# パッケージをインストール
COPY ./requirements.txt .
RUN pip install --upgrade pip setuptools \
&& pip install --no-cache-dir -r ./requirements.txt

# アプリケーションのソース
COPY ./app/ ./

requirements.txt

お好みで

3. 動作確認

3-1. VS CodeのRemote Containerを起動する

fastapi-testディレクトリをVS Codeで開いたら画面左下にある緑色のアイコンを押して、メニューの中から Open Folder in Container を開きます。

スクリーンショット 2022-04-24 11.59.25.png

Dockerイメージのビルドが始まるのでしばらく待ちます。

ビルドが完了すると、Pylanceの拡張を有効にするためのポップアップが表示されるので Yes を押してVS Codeを開き直します。

スクリーンショット 2022-04-24 12.03.41.png

3-2. アプリケーションを起動する

VS Codeからターミナルを開いて(ちなみにBashになっています)、uvicorn app.main:app --host 0.0.0.0 --reload でアプリケーション(main.py)を起動します。

スクリーンショット 2022-04-24 12.07.55.png

リンクを開いて {"Hello":"World"} が表示されていればOKです。
また、 FastAPIの公式ドキュメントのとおり、APIがたたけることも確認しておきます。

もちろん公式の通り/docsを開けばSwagger UIのドキュメントを確認できます。

スクリーンショット 2022-04-24 16.49.19.png

ちなみに、↑ではホストの8000番ポートが接続していますが、これはRemote Containerが自動的にフォワーディングする機能があるためです(便利ですね)。

スクリーンショット 2022-04-24 16.54.39.png

以上

6
5
2

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
6
5