概要
前回の続きです
ヘッダの情報に合わせて適切なルーティングをコールするようにしてみました
環境
- Python 3.11.3
- fastapi 0.100.1
- pydantic 2.1.1
サンプルコード
from typing import Self
from fastapi import Depends, FastAPI, Form, Request
from pydantic import BaseModel, field_validator
app = FastAPI()
async def get_action(request: Request) -> str:
action = request.headers.get("Action", "default")
return action
class UserForm(BaseModel):
username: str
password: str
@classmethod
def as_form(cls, username: str = Form(...), password: str = Form(...)) -> Self:
return cls(username=username, password=password)
@field_validator("username")
def validate_username(cls, v):
if v != "hawksnowlog":
raise ValueError("Invalid username.")
return v
@app.get("/")
async def root(request: Request, action: str = Depends(get_action)):
form_data = await request.form()
if action == "Hoge":
# FormData は immutableDict なのでアンパックできる
return await hoge(action, UserForm(**form_data)) # type: ignore
return action
@app.post("/hoge")
async def hoge(
action: str = Depends(get_action), form_data: UserForm = Depends(UserForm.as_form)
):
return action, form_data.username
動作確認
- pipenv run uvicorn app:app --reload
POST で送信できる
-
curl -XPOST -H "Action: Hoge" localhost:8000/hoge -H "content-type: application/x-www-form-urlencoded" -d "username=hawksnowlog&password=pass"
GET からも送信できる
-
curl -XGET -H "Action: Hoge" localhost:8000 -H "content-type: application/x-www-form-urlencoded" -d "username=hawksnowlog&password=pass"
どちらも username のバリデーションが動作していることも確認できると思います
最後に
同一パスに対する異なる処理を書きたい場合には使えるテクニックかなと思います
0 件のコメント:
コメントを投稿