Claude CodeでPython開発を始める実装ガイド|uv・pytest・ruff・FastAPI
Claude CodeでPython開発を始める手順。uv、venv、pyproject、pytest、ruff、FastAPIを初心者向けに実装で解説。
Pythonを学び始めた人がClaude Codeを使うと、最初の壁は「何を頼めばよいか」ではなく「どの状態なら動くプロジェクトと言えるか」です。ファイルは作れたのにimportで落ちる、仮想環境がずれる、テストはあるのに実行できない、という失敗はかなり起きます。
この記事では、Claude Codeに丸投げせず、初心者でもレビューできるPython開発の足場を作ります。対象は、uvまたはvenvで環境を作り、pyproject.tomlに依存関係を集め、pytestでテストし、ruffで整形と静的チェックを行い、FastAPIまたはCLIから小さく公開する流れです。
公式仕様は必ず一次情報で確認してください。Claude Codeの基本はClaude Code公式ドキュメント、Pythonのプロジェクト設定はPython Packaging User Guide、uvはAstralのuvドキュメント、テストはpytest公式、整形とlintはRuff公式、APIはFastAPI公式チュートリアルを参照します。
全体像を先に決める
Claude Codeはコードを書けますが、初心者が最初に決めるべきなのは「小さく動く単位」です。いきなり認証、DB、Docker、CIまで頼むと、エラーの原因が依存関係なのか、設計なのか、生成コードなのか切り分けられません。
最初の完成形は、次の4点で十分です。
uv run pytestでテストが通るuv run ruff check .とuv run ruff format .が動く- FastAPIなら
/tasksで1件作成できる - CLIなら
task-api add "買い物"のようにローカルで動く
flowchart LR
A["作業ブリーフ"] --> B["uv または venv"]
B --> C["pyproject.toml"]
C --> D["src 配下の実装"]
D --> E["pytest"]
E --> F["ruff"]
F --> G["Claude Codeに小さく修正依頼"]
ここでいうブリーフは、Claude Codeへの作業依頼書です。目的、変更してよいファイル、使うPythonバージョン、確認コマンドを書きます。harnessのような専門語を使うなら「エージェントが作業するための足場」と言い換えておくと、初心者チームでもレビューしやすくなります。
Claude Codeへ渡す依頼文
最初のプロンプトは長くなくて構いません。ただし、依存関係、テスト、実行コマンド、触ってよい範囲は必ず入れます。
このリポジトリにPython 3.12向けの小さなタスク管理APIを追加してください。
条件:
- パッケージ管理はuv、設定はpyproject.tomlに集約
- 実装はsrc/task_api/配下、テストはtests/配下
- FastAPIでPOST /tasksとGET /tasksを実装
- pytestで正常系と404系をテスト
- ruff checkとruff formatが通る形にする
- 変更前に計画を出し、変更後に実行した確認コマンドを報告する
触ってよい範囲:
- pyproject.toml
- src/task_api/**
- tests/**
この依頼文の狙いは、Claude Codeを「それっぽいコード生成」ではなく「検証まで行う実装担当」にすることです。特に初心者は、生成されたコードを読めても、プロジェクト構成の正しさまでは判断しにくいので、確認コマンドを依頼文に含めます。
既存プロジェクトで使う場合は、CLAUDE.mdの書き方ガイドも合わせて整えると、毎回同じルールを説明しなくて済みます。API設計を広げる段階ではClaude CodeでAPI開発を高速化する方法も参照してください。
uvとvenvで環境を作る
2026年時点では、個人開発や教材ではuvを使うと環境作成と依存解決が速く、説明もしやすくなります。ただし会社PCで新しいツールを入れられない場合は、標準のvenvでも構いません。大事なのは、Claude Codeに「どちらを使うか」を明示することです。
macOS/Linuxなら次の流れです。
mkdir task-api
cd task-api
uv init --app --python 3.12
uv add "fastapi[standard]"
uv add --dev pytest ruff
mkdir -p src/task_api tests
touch src/task_api/__init__.py
Windows PowerShellならディレクトリ作成だけ変えます。
mkdir task-api
cd task-api
uv init --app --python 3.12
uv add "fastapi[standard]"
uv add --dev pytest ruff
New-Item -ItemType Directory -Force src/task_api, tests
New-Item -ItemType File -Force src/task_api/__init__.py
uvが使えない場合の最小手順です。チーム記事や研修資料では、こちらも併記しておくとWindows利用者が詰まりにくくなります。
python -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install "fastapi[standard]" pytest ruff
python -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install --upgrade pip
python -m pip install "fastapi[standard]" pytest ruff
pyproject.tomlに設定を集める
Python初心者がつまずきやすいのは、requirements.txt、setup.cfg、pytest.ini、.ruff.tomlが分かれていて、どれを直せばよいか分からなくなる状態です。最初はpyproject.tomlに集約しましょう。
[project]
name = "task-api"
version = "0.1.0"
description = "Small FastAPI and CLI sample for Claude Code practice"
requires-python = ">=3.11"
dependencies = [
"fastapi[standard]>=0.115.0",
]
[project.scripts]
task-api = "task_api.cli:main"
[dependency-groups]
dev = [
"pytest>=8.0.0",
"ruff>=0.8.0",
]
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[tool.hatch.build.targets.wheel]
packages = ["src/task_api"]
[tool.pytest.ini_options]
testpaths = ["tests"]
pythonpath = ["src"]
[tool.ruff]
line-length = 100
target-version = "py311"
[tool.ruff.lint]
select = ["E", "F", "I", "B", "UP"]
この設定にしておくと、Claude Codeに「pyproject.tomlの設定に従って修正して」と頼めます。設定ファイルが分散しているより、差分レビューが楽です。
FastAPIとCLIを最小実装する
次のコードはDBを使わないインメモリ実装です。本番用ではありませんが、HTTP、型、テスト、エラー処理を学ぶ足場としては十分です。src/task_api/main.pyに置きます。
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel, Field
app = FastAPI(title="Task API")
class TaskCreate(BaseModel):
title: str = Field(min_length=1, max_length=80)
class Task(BaseModel):
id: int
title: str
done: bool = False
_tasks: dict[int, Task] = {}
_next_id = 1
@app.post("/tasks", response_model=Task, status_code=201)
def create_task(payload: TaskCreate) -> Task:
global _next_id
task = Task(id=_next_id, title=payload.title)
_tasks[task.id] = task
_next_id += 1
return task
@app.get("/tasks", response_model=list[Task])
def list_tasks() -> list[Task]:
return list(_tasks.values())
@app.patch("/tasks/{task_id}/done", response_model=Task)
def mark_done(task_id: int) -> Task:
task = _tasks.get(task_id)
if task is None:
raise HTTPException(status_code=404, detail="Task not found")
updated = task.model_copy(update={"done": True})
_tasks[task_id] = updated
return updated
ローカルで起動します。
uv run fastapi dev src/task_api/main.py
ブラウザでhttp://127.0.0.1:8000/docsを開くと、自動生成されたAPIドキュメントからPOSTを試せます。ここまで動いてからDBを足すほうが、Claude Codeの修正も追いやすくなります。
CLIも足すなら、src/task_api/cli.pyに置きます。
import argparse
import json
from pathlib import Path
DB_PATH = Path("tasks.json")
def load_tasks() -> list[dict[str, object]]:
if not DB_PATH.exists():
return []
return json.loads(DB_PATH.read_text(encoding="utf-8"))
def save_tasks(tasks: list[dict[str, object]]) -> None:
DB_PATH.write_text(json.dumps(tasks, ensure_ascii=False, indent=2), encoding="utf-8")
def add_task(title: str) -> dict[str, object]:
tasks = load_tasks()
task = {"id": len(tasks) + 1, "title": title, "done": False}
tasks.append(task)
save_tasks(tasks)
return task
def main() -> None:
parser = argparse.ArgumentParser(description="Task CLI")
subparsers = parser.add_subparsers(dest="command", required=True)
add_parser = subparsers.add_parser("add")
add_parser.add_argument("title")
args = parser.parse_args()
if args.command == "add":
task = add_task(args.title)
print(f"Added #{task['id']}: {task['title']}")
if __name__ == "__main__":
main()
uv run task-api add "pytestを書く"
pytestとruffで安全に反復する
Claude Codeに何度も修正させるなら、テストとlintが先です。tests/test_main.pyを作ります。
import pytest
from fastapi.testclient import TestClient
from task_api import main
from task_api.main import app
@pytest.fixture(autouse=True)
def clean_tasks() -> None:
main._tasks.clear()
main._next_id = 1
def test_create_and_list_tasks() -> None:
client = TestClient(app)
response = client.post("/tasks", json={"title": "Write pytest"})
assert response.status_code == 201
assert response.json()["title"] == "Write pytest"
list_response = client.get("/tasks")
assert list_response.status_code == 200
assert len(list_response.json()) == 1
def test_mark_done_returns_404_for_missing_task() -> None:
client = TestClient(app)
response = client.patch("/tasks/999/done")
assert response.status_code == 404
assert response.json()["detail"] == "Task not found"
確認コマンドは固定します。
uv run pytest
uv run ruff check .
uv run ruff format .
失敗したら、エラー全文をClaude Codeへ貼るのではなく、最初に「失敗したコマンド」「期待した結果」「変更してよい範囲」を添えます。たとえば「uv run pytestの2件目だけ直してください。API仕様は変えず、tests/test_main.pyかsrc/task_api/main.pyの最小差分で」と頼むと、無関係な大改修を避けやすくなります。
テスト設計を広げたい場合はClaude Codeテスト戦略完全ガイドも合わせて読むと、正常系だけで終わらないレビュー観点を作れます。
3つ以上の実用ユースケース
1つ目は、学習用APIです。FastAPIのルーティング、Pydanticによる入力検証、pytestの基本を同時に学べます。DBなしで始め、動いてからSQLiteやPostgreSQLを足すと、原因の切り分けが簡単です。
2つ目は、業務の小さな自動化CLIです。CSVの整形、ファイル名の一括変更、社内レポートの前処理などは、GUIを作るよりCLIのほうが早いことがあります。Claude Codeにargparse、ログ、エラー時の終了コードまで指定すると、使い捨てスクリプトから一段上がります。
3つ目は、既存コードのテスト追加です。動いているが怖くて直せないPythonコードに対し、Claude Codeへ「先に現状を固定するテストを書いて」と頼みます。すぐリファクタリングさせるより、壊れていないことを確認する足場が先です。
4つ目は、研修教材や社内テンプレートです。pyproject.toml、srcレイアウト、pytest、ruff、確認コマンドを一式にしておくと、新人や非Webエンジニアでも同じ出発点から学べます。ClaudeCodeLabの研修・相談では、このような小さな題材をチームの実務に寄せて設計します。
失敗例と落とし穴
よくある失敗は、Claude Codeに「Pythonアプリを作って」とだけ頼むことです。これだとpip、poetry、uv、requirements.txtが混ざることがあります。最初にパッケージ管理を指定してください。
2つ目は、srcレイアウトなのにテストからimportできない失敗です。pythonpath = ["src"]をpyproject.tomlに入れるか、パッケージとしてインストールできる設定にします。importエラーは初心者がもっとも時間を溶かしやすい部分です。
3つ目は、動くコードより先にDBや認証を足すことです。ログイン、JWT、マイグレーションを同時に生成すると、エラー時に学習になりません。まずインメモリ、次にSQLite、最後に本番DBという順番が安全です。
4つ目は、ruffの自動修正をレビューせずに受け入れることです。整形は便利ですが、未使用importの削除で将来使う予定のコードが消えることもあります。Claude Codeには「ruffの差分を説明してから適用」と頼むと安心です。
5つ目は、シークレットを貼ることです。APIキー、DBパスワード、顧客データはプロンプトに入れず、.env.exampleのようなダミー名で説明します。
収益化につなげる導線
Python記事は検索流入を取りやすい一方、単なるコマンド集だけではAdSenseにも商品導線にも弱くなります。実装コード、失敗例、検証結果、読者の次の一歩を入れて、学習体験として完結させることが大切です。
個人開発者なら、まず無料のチートシートやプロンプトテンプレートで反復練習します。何度も同じ依頼文を書く段階になったらClaude Code教材一覧を使うと、ブリーフ、レビュー、テスト依頼を型化できます。チームでPython導入、研修、既存コードの安全な改善を進める場合はClaude Code研修・相談につなげるのが自然です。
実際に試した結果
この記事で紹介した内容は、Masaが初心者向けのPython題材を作るときに使う順番で確認しました。最初にuv、pyproject.toml、pytest、ruffを固定すると、Claude Codeの生成結果がかなりレビューしやすくなります。特に「FastAPIを先に小さく動かす」「DBや認証を後回しにする」「失敗したコマンド単位で修正を頼む」の3点は、学習者が詰まった場所を説明しやすく、記事としても研修教材としても再利用しやすいと感じました。
まとめると、Claude CodeでPython開発を始めるなら、魔法のプロンプトよりも小さな足場が重要です。環境、設定、実装、テスト、整形、確認コマンドを1つの流れにしてから、機能を少しずつ足してください。
無料PDF: Claude Code はじめてのチートシート
まずは無料PDFで基本コマンドと最初の使い方をまとめて確認してください。登録後はそのままテンプレート集や導入相談にも進めます。
スパムは送りません。登録情報は厳重に管理します。
Claude Codeを仕事で使える形にしませんか?
無料PDFで基礎を固めたあと、すぐ使えるテンプレート集で試し、必要なら業務自動化や導入相談まで進められます。
この記事を書いた人
Masa
Claude Codeの実務活用、導入設計、収益導線改善を検証しているエンジニア。10言語の技術メディアを運営中。
関連書籍・参考図書
この記事のテーマに関連する書籍を楽天ブックスで探せます。
※ 当サイトは楽天市場のアフィリエイトプログラムに参加しています。上記リンクから商品をご購入いただくと、運営者に紹介料が支払われる場合があります。
関連記事
ObsidianメモをCLAUDE.mdに変えるClaude Code運用: 文脈を毎回説明しない仕組み
Obsidianの作業メモからCLAUDE.md用の運用ノートを作り、Claude Codeに安定した文脈を渡す方法。
Claude Code Revenue CTA Routing: 記事からPDF、Gumroad、相談へ送る設計
PVだけで終わらせず、読者の状態に合わせて無料PDF、Gumroad教材、導入相談へ分岐するCTA設計です。
Claude Codeチーム引き継ぎルール: レビュー、権限、収益導線まで渡す実務手順
Claude Codeの作業をチームで渡すための証拠、権限、ロールバック、無料PDF/Gumroad/相談導線の実務ルール。