開発tax-assistantメモ
背景
tax-assistantプロジェクトのocr_server.pyが1,075行に膨れ上がっていた。レシートAPI、Square連携API、クレカ明細API、実装計画APIなど複数の機能が1ファイルに詰め込まれており、見通しが悪くなっていた。
db.pyで同様のモジュール分割を行った経験があったため、同じパターンでocr_server.pyを分割することにした。
新しいディレクトリ構成
src/server/
├── __init__.py # FastAPI app インスタンス
├── config.py # 設定・定数
├── receipts.py # レシートAPI
├── square.py # Square連携API
├── creditcard.py # クレカ明細API
└── plans.py # 実装計画API
各ファイルの役割
__init__.py
FastAPIアプリケーションのエントリーポイント。各モジュールのルーターを集約する。
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from .receipts import router as receipts_router
from .square import router as square_router
from .creditcard import router as creditcard_router
from .plans import router as plans_router
app = FastAPI(title="OCR Server")
# CORS設定
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# ルーター登録
app.include_router(receipts_router)
app.include_router(square_router)
app.include_router(creditcard_router)
app.include_router(plans_router)
config.py
環境変数やパス定数を一元管理。
from pathlib import Path
# ベースディレクトリ
BASE_DIR = Path(__file__).parent.parent.parent
# データディレクトリ
DATA_DIR = BASE_DIR / "data"
RECEIPTS_DIR = DATA_DIR / "receipts"
receipts.py
レシートのOCR処理とCRUD操作を担当するAPIRouter。
from fastapi import APIRouter
router = APIRouter(prefix="/api/receipts", tags=["receipts"])
@router.get("/")
async def list_receipts():
...
@router.post("/ocr")
async def ocr_receipt():
...
square.py
Square決済との連携APIを担当。
creditcard.py
クレジットカード明細のインポートと突き合わせAPIを担当。
plans.py
実装計画の管理APIを担当。
起動方法の変更
変更前
python ocr_server.py
変更後
uvicorn server:app --port 8000 --reload
src/ディレクトリから実行する場合:
cd src
uvicorn server:app --port 8000 --reload
db.pyと同じパターン
以前db.pyを分割した際と同じアプローチを採用した。
- 機能ごとにファイルを分離
- APIRouterを使用してルーティングをモジュール化
__init__.pyでルーターを集約- 設定は
config.pyに集約
この分割により、各機能が独立して開発・テストしやすくなった。
得られた効果
- 可読性向上: 1,075行から各ファイル200-300行程度に分割
- 保守性向上: 機能ごとにファイルが分かれているため、修正箇所の特定が容易
- テスト容易性: 各モジュールを個別にテスト可能
- チーム開発対応: 複数人で同時に別機能を開発しやすい