はじめに

エンジニアの遠藤です。今回は久しぶりの PyCharm 記事です。
以前の投稿 で、 pycharm を使って serverless framework を step 実行する方法を記載しましたが、今回は serverless framework ではなく、 fast api の step 実行についてまとめておきます。

環境

今回の動作確認環境は以下の通りです。

  • MacBook Pro (Apple M1 Pro)
  • macOS Ventura 13.0.1
  • PyCharm 2021.3.2 (Professional Edition)
  • Docker Desktop Version 4.12.0 (85629)
  • Docker version 20.10.17, build 100c701

実行環境は local の python ではなく、 container 上の python になります。
今回使用するプロジェクトのサンプルは github にアップしていますので、適宜ご参照ください。

プロジェクトの準備

それではプロジェクトの新規作成から進めていきます。
プロジェクト作成から長々と解説いたしますので、その辺は興味ないよ、という方は 「PyCharm の設定」 まですっ飛ばしてください。

それでは新規プロジェクトを作成します。
PyCharm では標準で色々なテンプレートを用意してくれていますが、今回はせっかくなので、「FastAPI」をそのまま使わせてもらいます。

----------2023-01-12-21.39.15

New environment using はあとで消すので何でも良いです。
ここでは、 venv をそのまま選んでいます。

----------2023-01-12-21.39.59

すると、上記のようなプロジェクトテンプレートができあがります。

起動確認

出来上がったプロジェクトの再生ボタンをそのまま押下します。

----------2023-01-12-21.39.59_2

すると、再生ボタンがリロードボタンに変わります。
----------2023-01-12-22.12.26

画面の下部にも、ログが出てきます。
赤字なのでビビりますが、正常です。
----------2023-01-12-22.13.30

では、この状態で curl などをしてみましょう。
以下のような出力になれば正常に起動しています。

$ curl http://127.0.0.1:8000/
{"message":"Hello World"}

デバッグ実行してみる

続けて、このままデバッグ実行をしてみましょう。
以下の、虫マークを押します。
----------2023-01-12-22.14.53

起動状態は、通常の再生ボタンを押した時とほぼ変わりませんが、虫マークの右下に緑のポッチがつきます。

----------2023-01-12-22.18.13

では、13行目にブレークポイントを貼って、再度 curl してみます。

$ curl http://127.0.0.1:8000/hello/fuga
{"message":"Hello fuga"}

すると以下の通り、 name という変数に何が入っているか、などを step 実行で見ていくことができるようになります。
----------2023-01-12-21.41.47

実行環境を DockerCompose に移行する

Docker 関連のファイルを準備

プロジェクト直下に、以下のファイルを作成します。

  • docker-compose.yml
  • Dockerfile
  • requirements.txt

docker-compose.yml

docker-compose.yml の中身は最小構成で以下の内容のみとなっています。

version: "3"
services:
  fastapi:
    build: .
    container_name: "fastapi"
    tty: true
    volumes:
      - .:/usr/src
    environment:
      - STAGE=local
    ports:
      - "8000:8000"

Dockerfile

Dockerfile の中身も python3.9 に必要なライブラリをインストールしているだけです。
CMD として、 uvicorn の起動を渡しています。

FROM python:3.9-slim-buster

ENV APP_ROOT /usr/src

WORKDIR $APP_ROOT

ADD requirements.txt .

RUN apt-get update
RUN apt-get -y install vim curl

RUN pip install --no-cache-dir --upgrade pip
RUN apt-get -y install gcc && pip install --no-cache-dir -r requirements.txt && apt-get -y purge gcc

CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"]

requirements.txt

requirements.txt も、今回のサンプルを動かすのに最低限の内容だけ書いています。

fastapi
uvicorn

DockerCompose を立ち上げてみる

ここまでできたら、一度、 docker-compose を立ち上げてみましょう。
プロジェクト直下で以下のコマンドを実行します。

$  docker-compose up -d
[+] Running 1/1
 ⠿ Container fastapi  Started 

Started が表示されたら成功です。
docker のプロセスなどを見て生きていることを確認しても良いです。

$ docker ps                   
CONTAINER ID   IMAGE                    COMMAND                  CREATED          STATUS          PORTS                    NAMES
265be9276ea1   fastapiproject-fastapi   "uvicorn main:app --…"   55 seconds ago   Up 54 seconds   0.0.0.0:8000->8000/tcp   fastapi

再度 curl で FastAPI の動作確認をしてみます。

$ curl http://127.0.0.1:8000/hello/fuga
{"message":"Hello fuga"}

ちなみに、 up 時に -d オプションを付けなければ、 logger()print() の情報は terminal からでも確認できます。
以下の hogeprint("hoge") した際のログです。

 docker-compose up                    
[+] Running 1/0
 ⠿ Container fastapi  Created                                                                                                                                                                                  0.0s
Attaching to fastapi
fastapi  | INFO:     Will watch for changes in these directories: ['/usr/src']
fastapi  | INFO:     Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
fastapi  | INFO:     Started reloader process [1] using StatReload
fastapi  | INFO:     Started server process [7]
fastapi  | INFO:     Waiting for application startup.
fastapi  | INFO:     Application startup complete.
fastapi  | hoge
fastapi  | INFO:     172.20.0.1:62916 - "GET /hello/fuga HTTP/1.1" 200 OK

一旦、 local の docker は不要なので止めておきます。

$ docker-compose down

PyCharm の設定

いよいよ本題です。

Interpreter の変更

最初に Interpreter を変更する必要があります。
まずは Preferences を開きます。

[PyCharm] -> [Preferences...] をクリック
----------2023-01-12-21.54.41

開いたメニューの検索窓から 「Interpreter」 を検索します。
すると、「Python Interpreter」が見つかるので、選びます。
----------2023-01-12-21.55.15

現在設定中の Interpreter の右側の歯車を選択して、 [Add...] を選びます。
----------2023-01-12-21.55.45

続けて表示される Interpreter の一覧から、 [Docker Compose] を選びます。
----------2023-01-12-21.57.42

Configuration files: には用意した docker-compose.yml までの path を入力します。
(デフォルトで入っているはず。)

Service: には fastapi を選びます。
あとは [OK] -> [OK] とすすみます。

この時点で、最初に作成された venv は不要なので消してしまっても良いです。
プロジェクトの見た目は以下のようなものになっています。

----------2023-01-12-22.01.14

起動してみる

それでは、そのまま PyCharm から docker-compose を起動してみます。
起動は簡単で、以下の再生ボタンを押すだけです。
----------2023-01-12-22.01.14-1

すると、 fastapi の再生ボタンがリロードボタンになっており、起動していることが確認できます。
----------2023-01-12-22.01.28

また、画面下部のメニューから、 Service を辿っていくと、ログを見ることもできます。
以下は、 curl を実行した時のログの様子です。

----------2023-01-12-22.02.02

デバッグ実行するには

通常の開発であれば、ここまででも十分かなとは思いますが、デバッグ実行したいケースもあるかと思います。
ですが、このままの設定では、実行することができませんでした。
もし、Docker の CMD で起動したプロセスへのアタッチ方法をご存知の方がいましたら、教えていただきたいです。

というわけで、デバッグ実行のため、何箇所かコードに手を入れていきます。

Dockerfile

この Dockerfile 内で起動したプロセスに対して、アタッチができないようなので、この処理は止めておきます。

FROM python:3.9-slim-buster

ENV APP_ROOT /usr/src

WORKDIR $APP_ROOT

ADD requirements.txt .

RUN apt-get update
RUN apt-get -y install vim curl

RUN pip install --no-cache-dir --upgrade pip
RUN apt-get -y install gcc && pip install --no-cache-dir -r requirements.txt && apt-get -y purge gcc

# 以下をコメントアウト
# CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"]

main.py の起動処理

main.py の中に記載しても良いですし、別ファイルを作成しても大丈夫です。
サンプルでは、 main.py に直接手を入れいていますが、実際のプロジェクトでは、うっかり謎のゴミコードが残る懸念もあるので、 step 実行用の py ファイルを用意しても良さそうです。

import uvicorn

if __name__ == '__main__':
    uvicorn.run("main:app", host='0.0.0.0', port=8000, reload=True)

Configurations の追加

PyCharm の Configurations を追加します。
以下の [Edit Configurations..] から、 main.py を実行する設定を追加します。

----------2023-01-12-22.03.20

左上の + ボタンから、設定を追加します。
----------2023-01-12-22.04.01

  • を押すと色々と選択肢が出てきますが、 [Python] を選びます。

----------2023-01-12-22.04.21

Name には分かりやすいものを設定し、 Script path: には、 uvicorn.run を書いた python までの path を入力します。

----------2023-03-23-14.21.18

path の記載は、絶対パスでも、プロジェクトルートからの相対パスでも大丈夫です。

  • main.py
  • ./main.py
  • /Users/hoge/project/main.py

すると、 Configurations が以下のような見た目になります。

----------2023-01-12-22.04.52

デバッグ実行してみる

あとは、最初のデバッグ実行と同じように、虫マークを押せば、勝手に docker が起動し、デバッグ実行できるようになっています。

以下は、実際にブレークポイントで止めているところです。

----------2023-01-12-22.05.52

以上です。
知ってしまえば簡単ですね。

おわりに

ずぅーーーーーーっと前から、ステップ実行したいなぁと思っていたのですが、 print で乗り切れていたので、腰を入れて調べていませんでした。
ちょっとググると出てくる記事もあったのですが、イマイチどこの何を設定しているのか良くわからないものが多く、備忘録を兼ねて、プロジェクトの作成からまとめてみることにしました。

最初に設定だけできてしまえば、とても効率的に開発を進められると思いますので、みなさんも試してみてください。