Python初心者がFastAPIでTodo(API)を作ってみた
前提
Python 3.9
FastAPI 0.88
sqlmodel
sqlite3
開発環境
MacBook + VScode
FastAPIについて
特徴
公式より引用
- 高速: NodeJS や Go 並みのとても高いパフォーマンス (Starlette と Pydantic のおかげです)。 最も高速な Python フレームワークの一つです.
- 高速なコーディング: 開発速度を約 200%~300%向上させます。
- 少ないバグ: 開発者起因のヒューマンエラーを約 40%削減します。
- 直感的: 素晴らしいエディタのサポートや オートコンプリート。 デバッグ時間を削減します。
- 簡単: 簡単に利用、習得できるようにデザインされています。ドキュメントを読む時間を削減します。
- 短い: コードの重複を最小限にしています。各パラメータからの複数の機能。少ないバグ。
- 堅牢性: 自動対話ドキュメントを使用して、本番環境で使用できるコードを取得します。
- Standards-based: API のオープンスタンダードに基づいており、完全に互換性があります: OpenAPI (以前は Swagger として知られていました)
インストール
pythonは3.9がインストール済みの前提
FastAPIのインストール
pip3 install fastapi
uvicornサーバ
- httpdライブサーバ
pip3 install "uvicorn[standard]"
sqlmodelのインストール
- sqlite3のO/Rマッパー
pip3 install sqlmodel
開発
初期DBの作成とコネクションクラスの作成
初期DBの作成
models/init.py
from datetime import datetime
from typing import Optional
from sqlmodel import Field, SQLModel, create_engine
class Todo(SQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
content: str
created_at: datetime = Field(default=datetime.utcnow(), nullable=False)
updated_at: datetime = Field(default_factory=datetime.utcnow, nullable=False)
# DBへの接続を定義
sqlite_file_name = "todos.sql"
sqlite_url = f"sqlite:///{sqlite_file_name}" # エンジンデータベースのURL
engine = create_engine(sqlite_url, echo=True) # engineを作成
SQLModel.metadata.create_all(engine) # モデルからテーブルを生成
DB接続クラス
models/db.py
from sqlmodel import create_engine
# DBへの接続を定義
sqlite_file_name = "todos.sql"
sqlite_url = f"sqlite:///{sqlite_file_name}" # エンジンデータベースのURL
engine = create_engine(sqlite_url, echo=True) # engineを作成
メイン処理
main.py
import json
from fastapi import FastAPI
from sqlmodel import Field, SQLModel, create_engine, Session, select
from pydantic import BaseModel
from datetime import datetime
from typing import Optional
import models.db as Db
#SQL MODEL
class Todo(SQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
content: str
created_at: datetime = Field(default=datetime.utcnow(), nullable=False)
updated_at: datetime = Field(default_factory=datetime.utcnow, nullable=False)
#FORM MODELS
class TodoCreate(BaseModel):
content: str
class TodoUpdate(BaseModel):
id: int
content: str
class TodoDelete(BaseModel):
id: int
# main
app = FastAPI()
# hello world
@app.get("/")
async def root():
return {"message": "Hello World"}
# select list
@app.get("/todos/")
async def todo_list():
with Session(Db.engine) as session:
stmt = select(Todo)
results = session.exec(stmt)
todos = []
for todo in results:
todos.append(todo)
return {"todos": todos}
# select one
@app.get("/todos/{_id}")
async def todo_find(_id:int):
with Session(Db.engine) as session:
stmt = select(Todo).where(Todo.id == _id)
todo = session.exec(stmt).first()
return {"todo": todo}
# create
@app.post("/todo")
async def todo_create(todo :TodoCreate):
with Session(Db.engine) as session:
todo = Todo(content=todo.content)
session.add(todo)
session.commit()
return True
# update
@app.patch("/todo")
async def todo_update(todoUpdate :TodoUpdate):
with Session(Db.engine) as session:
stmt = select(Todo).where(Todo.id == todoUpdate.id)
todo = session.exec(stmt).first()
todo.content = todoUpdate.content
session.add(todo)
session.commit()
#更新したレコードの取得
stmt = select(Todo).where(Todo.id == todoUpdate.id)
todo = session.exec(stmt).first()
return todo
# delete
@app.delete("/todo")
async def todo_delete(todoDelete :TodoDelete):
with Session(Db.engine) as session:
stmt = select(Todo).where(Todo.id == todoDelete.id)
todo = session.exec(stmt).first()
session.delete(todo)
session.commit()
return True
動かしてみる
ライブサーバ(uvicorn)を起動
uvicorn main:app --reload
ソースを変更するとホットリロードされます。
Postmanで動作テスト
リストを取得する
todoを追加する
todoを更新する
todoを削除する
OpenAPIのドキュメントも自動生成される
ブラウザでドキュメントのURLにアクセスする
http://127.0.0.1:8000/docs
終わりに
FastAPIは軽くて小さなフレームワークだと思います。
プロトタイプなど、一時的にAPIを開発するには、簡単で軽い反面、いろいろやりたいことがある場合は、ライブラリをインストール必要があるかと思います。なので、依存関係などを管理するのは大変かもしれません。
ドキュメントやエコシステムが未発達なので、やりたいことを検索してもうまく情報が見つからない場合がある気がします。
プロダクションとかはDjangoとか実績のあるフレームワークのほうがいい気がします。
参考ページ
https://fastapi.tiangolo.com/ja/
https://zenn.dev/nameless_sn/articles/why_fastapi_development