はじめに
Pythonを使った開発では、
- 「Pythonを書けること」
- 「フレームワークを使えること」
- 「APIを作れること」
だけでは、実際のプロジェクトを最後まで成功させることはできません。
実際の開発現場では、コードを書く前に、
- クライアントの要望を整理する
- 本当に必要な機能を決める
- 技術的な実現方法を検討する
- 開発スケジュールを組む
- デザイン・仕様を確認する
- 開発メンバーと認識を合わせる
- テストする
- クライアントに確認してもらう
- リリースする
- リリース後の問題に対応する
といった、多くの工程があります。
この記事では、私がPythonを利用したWeb開発プロジェクトを進める際に意識していることを、プロジェクト開始から運用までの流れに沿って整理します。
「Pythonのコードを書く」という視点だけではなく、実際に一つのプロジェクトを完成させるためには何を考える必要があるのかを中心にまとめます。
1. プロジェクト開始時に、いきなりコードを書かない
Python案件を受注したとき、最初にやることは実装ではありません。
まず確認するのは、
「クライアントが本当に解決したい問題は何なのか?」
という点です。
例えば、クライアントから、
「社内業務を自動化するシステムを作りたい」
と言われたとします。
この時点では、まだ開発を開始できません。
なぜなら、
「何を自動化するのか」
が明確になっていないからです。
そこで、以下のような質問を整理します。
確認する内容
- 現在はどのような業務をしているのか
- 誰が利用するのか
- 1日に何件程度処理するのか
- 現在どのツールを使っているのか
- ExcelやCSVを利用しているのか
- 手作業になっている部分はどこか
- どこに時間がかかっているのか
- どの部分を自動化したいのか
- 最終的にどのような状態になれば成功なのか
この段階では、技術よりも業務理解を優先します。
2. クライアントの要望を「機能」に変換する
クライアントの話は、そのままでは開発仕様になっていないことが多いです。
例えば、
「ユーザーが簡単にデータを登録できるようにしたい」
という要望があったとします。
これを開発側では、もう少し具体化します。
例
ユーザー機能
- ログイン
- ログアウト
- ユーザー登録
- パスワード変更
- データ登録
- データ編集
- データ削除
- データ検索
- データ一覧表示
という形に分解します。
さらに、
「誰が利用するのか」
も考えます。
例えば、
- 一般ユーザー
- 管理者
- システム管理者
で権限が異なる場合、最初から設計に含める必要があります。
3. MVPを決める
実際のプロジェクトでは、最初からすべての機能を作ろうとすると開発期間もコストも膨らみます。
そのため、私はまず、
「最初のリリースで本当に必要な機能は何か?」
を整理します。
例えば100個のアイデアがあったとしても、初回リリースでは、
ログイン
↓
データ登録
↓
データ確認
↓
データ編集
↓
データ検索
という業務の中心部分だけを完成させます。
その後、
通知
↓
CSV出力
↓
自動集計
↓
AI機能
↓
外部サービス連携
などを追加していきます。
これは単純に開発を減らすためではありません。
実際にユーザーに使ってもらい、フィードバックを得るためです。
4. Pythonの技術スタックを決める
要件が整理できたら、技術選定に入ります。
例えばWeb APIを中心としたシステムであれば、以下のような構成を検討します。
Frontend
↓
REST API
↓
Python / FastAPI
↓
PostgreSQL
開発環境では、
Python
FastAPI
Pydantic
SQLAlchemy
PostgreSQL
Docker
Pytest
Git
GitHub Actions
などを組み合わせることができます。
ただし、重要なのは、
「最新技術を使うこと」
ではありません。
プロジェクトの規模、チームのスキル、保守性、納期、予算などを考えて決定します。
5. Pythonプロジェクトの構成を最初に決める
開発開始時にディレクトリ構成を決めておくと、後からコードが大きくなっても管理しやすくなります。
例えばFastAPIなら、
app/
├── main.py
├── api/
│ ├── routes/
│ │ ├── users.py
│ │ └── items.py
│ └── dependencies.py
├── models/
├── schemas/
├── services/
├── repositories/
├── core/
└── utils/
tests/
├── unit/
└── integration/
Dockerfile
docker-compose.yml
requirements.txt
のように責務を分けます。
ここで重要なのは、
Route
↓
Service
↓
Repository
↓
Database
のように、それぞれの役割を明確にすることです。
例えばAPIの処理の中に、
- DBアクセス
- ビジネスロジック
- バリデーション
- メール送信
などをすべて書いてしまうと、後から修正するのが難しくなります。
6. DB設計を先に考える
Webシステムでは、DB設計が非常に重要です。
例えばユーザーと注文情報を管理する場合、
users
├── id
├── name
├── email
└── created_at
orders
├── id
├── user_id
├── amount
├── status
└── created_at
のように関係性を整理します。
ここで、
users.id
↓
orders.user_id
というリレーションを設計します。
DB設計を曖昧なまま実装すると、後から、
- カラム追加
- データ移行
- SQL修正
- API修正
- 既存データへの影響確認
などが発生します。
そのため、私は実装前にER図やデータ構造を整理するようにしています。
7. API設計
次にAPIを設計します。
例えばユーザー登録なら、
POST /api/users
ユーザー取得なら、
GET /api/users/{id}
ユーザー更新なら、
PUT /api/users/{id}
ユーザー削除なら、
DELETE /api/users/{id}
といった形です。
ここでは、
- URL
- HTTP Method
- Request
- Response
- Status Code
- 認証
- エラー形式
まで決めます。
例えば成功時、
{
"id": 101,
"name": "Taro",
"email": "example@example.com"
}
エラー時、
{
"code": "USER_NOT_FOUND",
"message": "User was not found."
}
のように、レスポンス形式を統一します。
8. 実装開始
ここでようやくPythonの実装に入ります。
例えばFastAPIであれば、
from fastapi import FastAPI
app = FastAPI()
@app.get("/health")
def health_check():
return {
"status": "ok"
}
のような最小構成から始めることができます。
しかし、実際のプロジェクトでは、
「機能を作る」
だけではありません。
例えばユーザー登録機能なら、
Request
↓
Validation
↓
Business Logic
↓
Database
↓
Response
という流れを考えます。
9. バリデーションを入れる
ユーザーから送信されるデータは、必ずしも正しいとは限りません。
例えば、
{
"email": "abc"
}
というデータが送信された場合、正しいメールアドレスなのか確認する必要があります。
Pydanticを使えば、
from pydantic import BaseModel, EmailStr
class UserCreate(BaseModel):
name: str
email: EmailStr
のように入力値を定義できます。
これによって、
- 型チェック
- 必須項目
- 文字列長
- メール形式
などを管理できます。
10. Gitで変更を管理する
実際の開発ではGitを使って変更履歴を管理します。
例えば、
main
└── develop
├── feature/user-registration
├── feature/login
└── feature/order
のようなブランチ構成にします。
コミットメッセージも、
feat: add user registration API
fix: validate email format
refactor: separate user service
test: add user API tests
のように、何を変更したのか分かる形にします。
Gitは単なるバックアップではありません。
チームで安全に開発するための変更管理システムとして利用します。
11. コードレビュー
自分で書いたコードは、自分では問題に気づきにくいことがあります。
そのため、Pull Requestを作成してレビューします。
レビューでは、
- 可読性
- 命名
- セキュリティ
- SQL
- エラーハンドリング
- パフォーマンス
- テスト
- 保守性
などを確認します。
例えば、
data = get_data()
だけでは、
「何のデータなのか」
が分かりにくい場合があります。
user = get_user_by_id(user_id)
のように、意味が分かる命名にするだけでも保守性は変わります。
12. テスト
開発が終わったら、すぐにクライアントへ渡すわけではありません。
まずテストを行います。
私は大きく、
Unit Test
Integration Test
API Test
E2E Test
Manual Test
という観点で考えます。
例えば、
def test_health_check(client):
response = client.get("/health")
assert response.status_code == 200
assert response.json()["status"] == "ok"
のようなテストを書きます。
さらに、
- 正常系
- 異常系
- 境界値
- 権限エラー
- 存在しないID
- 重複データ
- 不正な入力
なども確認します。
13. 「動く」と「使える」は違う
ここは実際のプロジェクトで非常に重要だと感じる部分です。
開発者として、
「APIは正常に動いています」
と言っても、ユーザーからすると、
「操作しにくい」
ということがあります。
例えば、
保存ボタンが分かりにくい
↓
エラー内容が分からない
↓
何を入力すればよいのか分からない
という問題です。
つまり、
システムとして動くことと、ユーザーが問題なく使えることは別です。
そのため、クライアント確認の工程を必ず設けます。
14. クライアントへのデモ
ある程度完成した段階で、実際に触れる環境を用意します。
例えば、
Development
↓
Staging
↓
Client Review
↓
Production
という流れです。
クライアントには、
- 実際の画面
- 操作方法
- 現在完成している機能
- 未実装機能
- 確認してほしいポイント
を明確に伝えます。
ここで重要なのは、
「何となく触ってください」
ではありません。
例えば、
確認項目
1. ログインできるか
2. ユーザー登録できるか
3. データを登録できるか
4. データを編集できるか
5. 検索できるか
6. エラー表示が分かりやすいか
のように確認項目を用意します。
15. クライアントから修正依頼が来る
実際のプロジェクトでは、ほぼ必ず修正依頼が発生します。
例えば、
「登録ボタンをもう少し分かりやすくしてほしい」
「スマートフォンでも使いやすくしてほしい」
「この項目は入力必須にしてほしい」
などです。
ここで重要なのは、
すべてを「バグ」として扱わないことです。
例えば、
仕様通りに動かない
→ バグ
仕様にはない新しい機能
→ 追加要望
操作性を改善したい
→ UI/UX改善
と分類します。
この分類をしないと、プロジェクトの範囲が際限なく広がってしまいます。
16. 追加要望への対応
実案件では、
「せっかくなので、これも追加できますか?」
という相談がよくあります。
その場合、すぐに「できます」と回答するのではなく、
追加機能の内容
↓
必要工数
↓
既存機能への影響
↓
スケジュールへの影響
↓
追加費用
を確認します。
例えば、
追加機能A
開発:2日
追加機能B
開発:4日
既存API修正:1日
テスト:1日
というように整理します。
その上でクライアントに説明します。
17. セキュリティ確認
Python Webシステムでは、セキュリティも重要です。
最低限、
- パスワードのハッシュ化
- SQL Injection対策
- XSS対策
- CSRF対策
- 認証・認可
- APIアクセス制御
- ファイルアップロード制限
- Secretsの管理
- ログ管理
- HTTPS
などを確認します。
特に、
.env
API Key
Database Password
Secret Key
などをGitリポジトリへコミットしないことは基本です。
18. Dockerで環境を統一する
開発者のPCでは動くのに、サーバーでは動かない。
これは開発現場でよくある問題です。
そこでDockerを利用します。
例えば、
Docker
├── Python
├── FastAPI
└── PostgreSQL
という環境を用意します。
これにより、
Developer PC
↓
Staging
↓
Production
で環境差を小さくできます。
19. CI/CD
さらにプロジェクトが大きくなった場合は、CI/CDも導入します。
例えば、
git push
↓
GitHub Actions
↓
Lint
↓
Test
↓
Build
↓
Deploy
という流れです。
コードをPushすると自動的にテストされ、
Test OK
なら次の工程へ進めるようにします。
これによって、手作業によるミスを減らせます。
20. 本番リリース
テストが完了したら、いよいよ本番環境へリリースします。
ただし、本番リリース直前に確認することは多くあります。
リリース前チェック
□ DBバックアップ
□ 環境変数確認
□ HTTPS確認
□ API確認
□ ログ確認
□ エラーハンドリング確認
□ 権限確認
□ 管理者アカウント確認
□ 外部サービス連携確認
□ 本番データ確認
特にDBバックアップは重要です。
何か問題が発生した場合に、復旧できる状態を作っておきます。
21. リリース後が本当のスタート
システムをリリースしたら、プロジェクト終了。
私はそう考えていません。
むしろ、
リリース後から本当の意味でユーザーのフィードバックが集まり始める
と考えています。
実際に利用されると、
思ったよりこの機能を使う
↓
この操作は分かりにくい
↓
この処理に時間がかかる
↓
このデータも見たい
といった新しい課題が見えてきます。
そこで、
利用
↓
データ・フィードバック収集
↓
課題整理
↓
優先順位付け
↓
改善
↓
再リリース
というサイクルを回します。
22. PMとして最も重要だと感じること
Python開発を経験してきて、技術力と同じくらい重要だと感じるのが、
「認識を合わせる能力」
です。
例えば開発者は、
「予約機能を実装しました」
と考えていても、クライアントは、
「予約後に自動でメールまで送られると思っていた」
かもしれません。
この認識の違いは、開発終盤で発覚すると大きな問題になります。
そのため、
要件
↓
仕様
↓
デザイン
↓
実装
↓
テスト
↓
確認
の各段階で、認識を合わせることが重要です。
23. 私が実際のプロジェクトで意識している開発サイクル
最終的には、以下のサイクルを意識しています。
【1】ヒアリング
↓
【2】要件整理
↓
【3】仕様確定
↓
【4】技術選定
↓
【5】DB/API設計
↓
【6】UI/UX設計
↓
【7】実装
↓
【8】コードレビュー
↓
【9】テスト
↓
【10】ステージング
↓
【11】クライアント確認
↓
【12】修正
↓
【13】本番リリース
↓
【14】監視・運用
↓
【15】改善
このサイクルを繰り返すことで、単純に「コードを書くプロジェクト」から、
「実際にユーザーに価値を提供するプロジェクト」
へ変わっていきます。
24. Python開発で大切なのは、Pythonだけではない
Pythonは非常に強力な言語です。
Web API、AI、機械学習、データ処理、自動化、バックエンドなど、さまざまな領域で利用できます。
しかし、実際のプロジェクトでは、
Python
+
Database
+
API
+
Cloud
+
Security
+
Testing
+
Git
+
CI/CD
+
Communication
+
Project Management
という複数の要素を組み合わせる必要があります。
特に受託開発では、
「どんなコードを書くか」
だけではなく、
「なぜこの機能が必要なのか」
「誰が使うのか」
「どうすれば安全にリリースできるのか」
「どうすれば運用し続けられるのか」
まで考える必要があります。
まとめ
Python開発プロジェクトを成功させるためには、実装力だけでは十分ではありません。
私が重要だと考えているのは、
- クライアントの課題を理解する
- 要望を具体的な仕様へ変換する
- MVPを決める
- 適切な技術を選定する
- DB/APIを設計する
- 保守しやすい構成で実装する
- テストを行う
- クライアントと認識を合わせる
- フィードバックを反映する
- 安全にリリースする
- リリース後も改善する
という一連のプロセスです。
Pythonはあくまで「開発のための道具」の一つです。
本当に重要なのは、
「技術を使って、ユーザーやクライアントの問題をどう解決するか」
だと考えています。
これからPythonを使って開発を始める方や、エンジニアとしてさらに上流工程まで担当したい方にとって、この記事が少しでも参考になれば幸いです。
最後まで読んでいただき、ありがとうございました。
