[メモ]FastAPIの構造を理解する

定義(pyproject.toml や models.py)から、メインのAPI処理(app/main.py)まで書いてみる。

【構成】


project/
├── pyproject.toml        # ライブラリの定義
├── alembic.ini           # DBマイグレーション設定
├── migrations/           # マイグレーションファイル(自動生成)
├── src/                  # 自作ライブラリ(コアロジック)
│   └── core/
│       ├── __init__.py
│       ├── models.py      # DBテーブル定義
│       └── engine.py      # SP計算ロジック
└── app/                  # FastAPI本体
    └── main.py

ライブラリの定義

project.toml

[build-system]
requires = ["setuptools>=61.0"] #setuptoolsのversion61.0を使う
build-backend = "setuptools.build_meta" #バッグエンド作業担当

[project]
name = "core"
version = "0.1.0"
description = "コアエンジン"
dependencies = [
    "fastapi",
    "uvicorn",
    "sqlalchemy",
    "alembic",
    "pydantic",
    "pydantic-settings"
]

[tool.setuptools.packages.find]
where = ["src"] # パッケージはsrc配下

models.py

from sqlalchemy import Column,Integer,String,Float
from sqlalchemy.orm import declarative_base

Base = declarative_base()

class Player(Base):
    __tablename__ = "players" # DB内でのテーブル名

    id = Column(Integer,primary_key=True,index=True)
    name = Column(String,unique=True)
    sp = Column(Float,default=100.0)
    level = Column(Integer,default=1)

ライブラリのインストール

pip install -e .

※pyproject.tomlと同じ階層にsrcが存在しないとエラーになります。

DBマイグレーションの自動化(Alembic) の準備

Alembicの初期化

alembic init migrations

alembic.iniの修正

SQLiteを使ってmyproject.dbという名前のDBファイルを作る

;sqlalchemy.url = driver://user:pass@localhost/dbname
sqlalchemy.url = sqlite:///./myproject.db

__file__:今いるところ

dirname:そのファイルが入っているフォルダ

abspath:相対的な場所

sys.path:絶対的な場所

env.py

import sys
from os.path import abspath,dirname
sys.path.insert(0,abspath(dirname(dirname(__file__)))) #パスを通す

# 自作ライブラリからBaseをインポート
from core.models import Base

#書き換える
# target_metadata = None
target_metadata = Base.metadata

設計図の作成

”--autogenerate”は、models.pyにはテーブルが設定されているのに

実際のデータベースにはまだないという差分を見つけ出します。

.bash

alembic revision --autogenerate -m "create player table"

migrations/versions/の中にテーブルを作る

マイグレーションに関する台本(スクリプト)は migrations というフォルダに入れる

alembic.ini

script_location = %(here)s/migrations

migrations/env.py

config = context.config

migrationsとversionsをくっつけている。

alembic.script.base.ScriptDirectory

https://github.com/sqlalchemy/alembic/blob/7b510dc52c7e931f393b6387f183bf888a08dee9/alembic/script/base.py

env.py 内の context オブジェクトに、保存先のフォルダ情報が渡される。

env.py

    context.configure(
        url=url,
        target_metadata=target_metadata,
        literal_binds=True,
        dialect_opts={"paramstyle": "named"},
    )

設計図をDBに適用(=マイグレート)

.bash

alembic upgrade head

メインファイル作成

自作ライブラリ(core)をインポートして,DBと連携する。

app/main.py

from fastapi import FastAPI, Depends
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker, Session
from asagaya_core.models import Player  # 自作ライブラリから呼び出し!

# 1. DB接続の設定
SQLALCHEMY_DATABASE_URL = "sqlite:///./myproject.db"
engine = create_engine(SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False})
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

app = FastAPI()

# 2. DBセッションの管理(Djangoの connection みたいなもの)
def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()

# 3. エンドポイント(APIの窓口)
@app.get("/")
def read_root():
    return {"message": "ようこそ"}

@app.get("/players")
def get_players(db: Session = Depends(get_db)):
    # DBから全プレイヤーを取得
    players = db.query(Player).all()
    return players

動作確認(pyproject.toml配下で)

.bash

uvicorn app.main:app --reload

ブラウザ

http://127.0.0.1:8000/

上だとDBにデータが空なので、

app/main.py 

from fastapi import Body 

# --- 既存のコードの下に ---

@app.post("/players")
def create_player(name: str = Body(...), db: Session = Depends(get_db)):
    new_player = Player(name=name, sp=100.0, level=
    db.add(new_player)
    db.commit()          
    db.refresh(new_player) # DBで発行されたIDなどを読み込み直す
    
    return {"message": "プレイヤーを登録しました", "player": new_player}

タイトルとURLをコピーしました