0
0

Fast APIを試してみた

Posted at

背景・目的

FastAPIに触れる機会があったので、基本的な特徴などを整理します。

まとめ

下記に特徴を整理します。

特徴 説明
FirstAPI 標準のPython型ヒントに基づいてPythonでAPIを構築するためのモダンなハイパフォーマンスなWebフレームワーク
特徴 ・高速
・高速なコーディング
・少ないバグ
・直感的
・簡単
・簡潔
・堅牢
・標準ベース
Requirements 下記を前提にしています。
・Starlette
・Pydantic
Dependencies 下記に依存しています。
・Pydantic
・Starlette
FastAPI CLI FastAPI アプリの提供、FastAPI プロジェクトの管理などに使用できるコマンドラインプログラム

開発モードと本番モードをパラメータによって分ける
ライセンス MITライセンス

概要

コンセプト

下記を基に整理します。

  • FirstAPIは、標準のPython型ヒントに基づいてPythonでAPIを構築するためのモダンなハイパフォーマンスなWebフレームワークです

  • 主な特徴は下記の通り

    • 高速
      • Node JSやGoと同等の非常に高いパフォーマンス
      • Pythonフレームワークの中で最も高速
    • 高速なコーディング
      • 開発速が200%〜300%向上する
    • バグの減少
      • 開発者によるエラーの約40%を削減する
    • 直感的
      • 優れたエディタのサポート
      • 完成されている
      • デバックにかかる時間が短縮される
    • 簡単
      • 簡単に使いやすく学びやいように設計されている
      • ドキュメントを読む時間が短縮される
    • 簡潔
      • コードの重複を最小限にする
      • 各パラメータ宣言からの複数の機能
      • バグが少なくなる
    • 堅牢
      • 本番に対応したコードの取得
      • 自動対話型ドキュメントを使用する
    • 標準ベース
      • APIのオープンスタンダードに基づいている
      • OpenAPI、JSONスキーマに準拠

Requirements

下記を前提にしています。

Dependencies

Fast APIは、PydanticとStarletteに依存しています。

  • Pydantic
    • email-validator
      • メールの検証用
  • Starlette
    • httpx
      • TestClientを使用する場合は必須
    • jinja2
      • デフォルトのテンプレート構成を使用する場合は必須
    • python-multipart
      • request.formを使用してフォームの解析をする場合に必須
  • FastAPI / Starlette
    • uvicorn
      • アプリケーションをロードして提供するサーバ用
      • 高いパフォーマンスの提供に必要ないくつかの依存関係が含まれる
    • fastapi-cli
      • fastapiコマンドを提供

追加のオプションの依存関係

  • Pydantic
    • pydantic-setting
      • 設定管理
    • pydantic-extra-types
      • Pydanticで使用される追加の型
  • FastAPI
    • orjson
      • ORJSONResponseを使用する場合
    • ujson
      • UJSONResponseを使用する場合

License

MIT ライセンス

FastAPI CLI

  • FastAPI CLI は、FastAPI アプリの提供、FastAPI プロジェクトの管理などに使用できるコマンドラインプログラムである
  • FastAPI をインストールすると fastapi-cli というパッケージが含まれる。このパッケージはターミナルで fastapi コマンドを提供する
  • 開発用に FastAPI アプリを実行するには、fastapi dev コマンドを使用できる
  • fastapiというコマンドは、fastapi cliを指す
  • FastAPI CLI は、Python プログラム (main.py など) へのパスを取得し、FastAPI インスタンス (通常は app という名前) を自動的に検出し、正しいインポート プロセスを決定して、それを提供する
  • 本番環境では、代わりに fastapi run を使用する
  • FastAPI CLI は内部的に、高性能で実稼働対応の ASGI サーバーである Uvicorn を使用する

fastapi dev

fastapi dev を実行すると、開発モードが開始される。

  • デフォルトでは自動リロードが有効になっており、コードを変更するとサーバーが自動的にリロードされる
    • これはリソースを大量に消費するため、無効にした場合よりも安定性が低下する可能性がある
  • 開発のみに使用する
  • IP アドレス 127.0.0.1 もListenする
    • マシンがそれ自体 (ローカルホスト) とのみ通信するための IP

fastapi run

fastapi run を実行すると、デフォルトで実稼働モードで FastAPI が開始される。

  • デフォルトでは、自動リロードは無効になっている
  • IP アドレス 0.0.0.0 もリッスンする
    • これは、使用可能なすべての IP アドレスを意味する
    • これにより、マシンと通信できるすべてのユーザーがパブリックにアクセスできるようになる
  • 通常、実稼働環境 (コンテナーなど) で実行する方法
  • ほとんどの場合、HTTPS を処理する「terminal proxy」をトップに置くことになる
  • これはアプリケーションのデプロイ方法によって異なる
  • プロバイダーがこれを行う場合もあれば、自分でセットアップする必要がある場合もある

実践

Installation

下記を基に試します。

  1. fastapiをインストールします
    $ pip install fastapi
    

Example

下記を基に試します。
https://fastapi.tiangolo.com/#example

Create it

  1. main.pyファイルに下記のコードを書きます
    from typing import Union
    
    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: Union[str, None] = None):
        return {"item_id": item_id, "q": q}
    

Run it

fastapi devコマンドにより、上記で作成したmain.pyファイルを読み取り、
その中のFastAPIアプリを検出し、Uvicornを使用してサーバを起動します。

デフォルトでは、fastapi devはローカル開発用に自動リロードを有効にして起動します。

  1. 下記のコマンドを実行します
fastapi-tutorial % ls main.py 
main.py
% fastapi dev main.py
INFO     Using path main.py                                                                                                                                                                                                      
INFO     Resolved absolute path /XXXXX/XXXXX/XXXXX/fastapi-tutorial/main.py                                                                                                                                                    
INFO     Searching for package file structure from directories with __init__.py files                                                                                                                                            
INFO     Importing from /XXXXX/XXXXX/XXXXX/fastapi-tutorial                                                                                                                                                                    
                                                                                                                                                                                                                                 
 ╭─ Python module file ─╮                                                                                                                                                                                                        
 │                      │                                                                                                                                                                                                        
 │  🐍 main.py          │                                                                                                                                                                                                        
 │                      │                                                                                                                                                                                                        
 ╰──────────────────────╯                                                                                                                                                                                                        
                                                                                                                                                                                                                                 
INFO     Importing module main                                                                                                                                                                                                   
INFO     Found importable FastAPI app                                                                                                                                                                                            
                                                                                                                                                                                                                                 
 ╭─ Importable FastAPI app ─╮                                                                                                                                                                                                    
 │                          │                                                                                                                                                                                                    
 │  from main import app    │                                                                                                                                                                                                    
 │                          │                                                                                                                                                                                                    
 ╰──────────────────────────╯                                                                                                                                                                                                    
                                                                                                                                                                                                                                 
INFO     Using import string main:app                                                                                                                                                                                            
                                                                                                                                                                                                                                 
 ╭────────── FastAPI CLI - Development mode ───────────╮                                                                                                                                                                         
 │                                                     │                                                                                                                                                                         
 │  Serving at: http://127.0.0.1:8000                  │                                                                                                                                                                         
 │                                                     │                                                                                                                                                                         
 │  API docs: http://127.0.0.1:8000/docs               │                                                                                                                                                                         
 │                                                     │                                                                                                                                                                         
 │  Running in development mode, for production use:   │                                                                                                                                                                         
 │                                                     │                                                                                                                                                                         
 │  fastapi run                                        │                                                                                                                                                                         
 │                                                     │                                                                                                                                                                         
 ╰─────────────────────────────────────────────────────╯                                                                                                                                                                         
                                                                                                                                                                                                                                 
INFO:     Will watch for changes in these directories: ['/XXXXX/XXXXX/XXXXX/fastapi-tutorial']
INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO:     Started reloader process [72826] using WatchFiles
INFO:     Started server process [72830]
INFO:     Waiting for application startup.
INFO:     Application startup complete.

Check it

上記で作成したmain.pyと、起動されたfastapiを使用してブラウザから挙動を確認します。

  1. ブラウザから、http://127.0.0.1:8000/items/5?q=somequeryを開きます

  2. 下記が表示されした

  3. 次に、ブラウザからhttp://127.0.0.1:8000/(items以降とパラメータなし)を開いてみます

  4. Hello worldが表示されました

Interactive API docs

APIドキュメントを確認してみます。Swagger UIが表示されます。

  1. ブラウザからhttp://127.0.0.1:8000/docsを開きます
  2. 下記が表示されました
    image.png

Alternative API docs

もう一つ、APIドキュメントを確認します。redocが表示されます。

  1. ブラウザからhttp://127.0.0.1:8000/redocを開きます
  2. 下記が表示されました
    image.png

Example upgrade

PUT リクエストから本文を受け取るようにファイル main.py を変更します。
Pydantic により、標準の Python 型を使用して本体を宣言します。

  1. main.pyを下記のように変更します。(追加した箇所には、Addedのコメントを残しています)
    from typing import Union
    
    from fastapi import FastAPI
    # Added
    from pydantic import BaseModel
    
    app =FastAPI()
    
    # Added
    class Item(BaseModel):
        name: str
        price: float
        is_offer: Union[bool, None] = None
    
    @app.get("/")
    def read_root():
        return {"Hello": "World"}
    
    @app.get("/items/{item_id}")
    def read_item(item_id: int, q: Union[str, None] = None):
        return {"item_id": item_id, "q": q}
    
    # Added
    @app.put("/items/{item_id}")
    def update_item(item_id: int, item: Item):
        return {"item_name": item.name, "item_id": item_id}
    
  2. ファイルを保存すると、自動リロードされます。(便利です)
    WARNING:  WatchFiles detected changes in 'main.py'. Reloading...
    INFO:     Shutting down
    INFO:     Waiting for application shutdown.
    INFO:     Application shutdown complete.
    INFO:     Finished server process [73765]
    INFO:     Started server process [73811]
    INFO:     Waiting for application startup.
    INFO:     Application startup complete.
    

Interactive API docs upgrade

上記のPutメソッド追加したので、APIドキュメントを確認します。

  1. ブラウザからhttp://127.0.0.1:8000/docsを開きます

  2. 追加されていました
    image.png
    image.png
    image.png

  3. 「Try it out」をクリックし、パラメータを入力してみます
    image.png

  4. ①「item_id」、②「Requrest body」を変更して、③「Execute」をクリックします
    image.png

  5. curlでリクエストされ、サーバで処理されました
    image.png

  6. fastapiのログからも「200」が返されていました

    INFO:     127.0.0.1:51929 - "GET /docs HTTP/1.1" 200 OK
    INFO:     127.0.0.1:51929 - "GET /openapi.json HTTP/1.1" 200 OK
    INFO:     127.0.0.1:51937 - "PUT /items/1 HTTP/1.1" 200 OK
    

Alternative API docs upgrade

redocでも確認します。

  1. ブラウザで、http://127.0.0.1:8000/redocを開きます

  2. 下記が表示されました。(putのUpdate Itemが追加されています)

    image.png

考察

今回、FastAPIを試してみました。下記が便利と感じました。今後もチュートリアルを通して理解を深めたいと思います。

  • 少量のコード
  • わかりやすい記述
  • OpenAPIドキュメントを自動で作成
  • 自動リロード

参考

0
0
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
0
0