Open7

fastapiメモ

TKDTKD

uvicorn: Python用のASGIサーバー

$ uvicorn main:app --reload

main: main.pyファイル (Python "module")。
app: main.py内部で作られるobject(app = FastAPI()のように記述される)。main.py内の変数名をuvicornの引数で使う
--reload: コードの変更時にサーバーを再起動させる。開発用。

パスオペレーションデコレータ
このデコレーターは直下の関数がオペレーション getを使用したパス/に対応することをFastAPI に通知する

#パスオペレーションデコレータ
@app.get("/")
#パスオペレーション関数
async def root():
    return {"message": "Hello World"}

例)
@app.post()
@app.put()
@app.delete()
@app.options()
@app.head()
@app.patch()
@app.trace()

パスパラメータ
@app.get("/items/{item_id}")
async def read_item(item_id: int):
return {"item_id": item_id}

path operations は順に評価される.
パスパラメータを使う場合は,固定値を先に宣言しておく必要がある.

パスパラメータを受け取る path operation をもち、有効なパスパラメータの値を事前に定義したい場合は、標準のPython Enum を利用
例)class ModelName(str, Enum):
alexnet = "alexnet"
resnet = "resnet"
lenet = "lenet"
これでmodel_name: ModelNameとして,型指定しておくと,{model_name}のpathをEnumで宣言した3種類に制限できる.
列挙型メンバと比較:model_name == ModelName.alexnet:
実際の値を比較:model_name.value == "lenet":

  • ファイルパスが必要な場合
    @app.get("/files/{file_path:path}")
TKDTKD
  • クエリパラメータ
    URL内で?のあとに書かれて,&で区切られてる
    使うには,pathパラメータにかかれていない変数をパスオペレーション関数の引数に宣言する.
    @app.get("/items/")
    async def read_item(skip: int = 0, limit: int = 10):
    return fake_items_db[skip : skip + limit]

クエリパラメータを必須にしたい場合は、デフォルト値を宣言しない
デフォルト引数をNoneにしておくと,オプション変数(なくてもOK)として扱える.

複数のパスパラメータとクエリパラメータを同時に宣言できます。FastAPIは互いを区別できる.

TKDTKD

from typing import Optional
OptionalでNoneがくる可能性がある型を宣言できる.
Optional[int]でint型かNone

リクエストボディ:クライアント→API
レスポンスボディ:API→クライアント

リクエストボディを読み取るには,Pydanticを使う

class Item(BaseModel):
    name: str
    description: Optional[str] = None
    price: float
    tax: Optional[float] = None

これを引数の型に指定する

変数.dict()で要素にアクセスする変数を作れる

TKDTKD

バリデーションの追加

  1. fastapiからQueryをインポート
  2. Query(None, max_length=50))のように条件をつけて,引数の既定値に設定する.

Queryに指定できるパラメータ

  • min_length
  • max_length
  • regex
  • 既定値
    これは第一位置引数にしていする
    例) Query("fixedquery", min_length=3))
  • 必須引数にする
    ...をつける
    Query(..., min_length=3))
  • ListでQueryパラメータを受け取る
    Listをtypingからimport, Optionalと組み合わせる
    async def read_items(q: Optional[List[str]] = Query(None)):

複数のボデイを扱う
pydanticを使う
BaseModelを継承してパラメータ分のクラスを定義.パスオペレーション関数の引数に指定する.

{
    "item": {
        "name": "Foo",
        "description": "The pretender",
        "price": 42.0,
        "tax": 3.2
    },
    "user": {
        "username": "dave",
        "full_name": "Dave Grohl"
    }
}

itemとuserでクラスを作っておくと,JSONをパースしてそれぞれの変数に代入できる.

TKDTKD

Response Model

httpリクエストのルーティング

@app.get()
@app.post()
@app.put()
@app.delete()

apiのルーティング
APIRouterをimport, @router.<メソッド>(パス)でappのときと同じように関数を登録する

main側ではファイルをimportして,routerを登録する

from fastapi import FastAPI
#api.routerは@routerを書いてあるファイルを置いたディレクトリ
from api.routers import ファイル名

app = FastAPI()
app.include_router(ファイル名.router)

returnを次のように**task_body.dict()とすると,引数にdictのkey,valueを展開してくれる
task_schema.TaskCreateResponse(id=1,**task_body.dict())

titleとdoneをkeyにもってる場合,
title=task_body.title, done=task_body.doneと同じ

TKDTKD

SQLデータベース

mysqlとの接続

sqlalchemy: ORMライブラリ
aiomysql: MySQL向けに非同期IO処理を提供するライブラリ
pymysql: MySQL向け非同期IO処理

docker-compose exec db mysql demoでMySQLクライアント起動できる