fastapiメモ
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}")
- クエリパラメータ
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は互いを区別できる.
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()で要素にアクセスする変数を作れる
バリデーションの追加
- fastapiからQueryをインポート
-
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をパースしてそれぞれの変数に代入できる.
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
と同じ
SQLデータベース
- postgreSQL + fastapi
FastAPIとPostgreSQLを使った公式のプロジェクトジェネレータ.フロントエンドやその他のツールも含め、すべてDockerをベースにしている
https://github.com/tiangolo/full-stack-fastapi-postgresql
mysqlとの接続
sqlalchemy: ORMライブラリ
aiomysql: MySQL向けに非同期IO処理を提供するライブラリ
pymysql: MySQL向け非同期IO処理
docker-compose exec db mysql demoでMySQLクライアント起動できる