FastAPI — Hello World
テクノロジ系 / L11 fastapi-basic — FastAPI 入門
FastAPI — Hello World
このトピックの前提
*(図は省略)*
> HTTP・API の仕組みは 未知でよい。これから説明する。
このトピックが終わると何ができるか
*(図は省略)*
今日のゴール: Python 5行でこれを動かす
Web API とは
「URL を打ったらデータが返ってくる仕組み」
*(図は省略)*
JSON はプログラム同士がデータをやり取りするときの共通フォーマット。Python の dict {"key": "value"} がそのまま JSON になる。
FastAPI が何をしてくれるか
「URL と Python 関数を結びつける」のが FastAPI の仕事
*(図は省略)*
さらに自動でやってくれること: Swagger UI の自動生成 / リクエストの型チェック / エラー整形
コードを読む — 全体像
from fastapi import FastAPI # ① FastAPI をインポート
app = FastAPI() # ② アプリのインスタンスを作る
@app.get("/") # ③ URL と HTTP メソッドを指定
def hello(): # ④ 関数を定義する
return {"message": "Hello World"} # ⑤ 返したいデータを return*(図は省略)*
① import と ② app
from fastapi import FastAPI # FastAPI ライブラリから FastAPI クラスを持ってくる app = FastAPI() # API の「本体」を作る。変数名は app が慣習
*(図は省略)*
> app という名前は起動コマンド uvicorn main:app と一致させる必要がある。
③ デコレータ — URL と関数をつなぐ
@app.get("/") # ← これがデコレータ
def hello():
...*(図は省略)*
④⑤ 関数と return
def hello():
return {"message": "Hello World"}*(図は省略)*
- return した dict がそのまま JSON になる
- リスト
[...]を return すると JSON 配列になる
サーバーを起動する
uvicorn main:app --reload
*(図は省略)*
ブラウザで確認する
*(図は省略)*
> localhost = 自分のパソコン。起動中のみアクセスできる。インターネット非公開。
Swagger UI を使う
http://localhost:8000/docs を開く
*(図は省略)*
> Swagger UI は FastAPI が自動生成する。コードを書くだけで操作画面ができる。
複数のエンドポイントを並べる
同じ app に対して @app.get() を何個でも並べて書ける。これが「API を増やしていく」感覚。
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def hello():
return {"message": "Hello World"}
@app.get("/ping")
def ping():
return {"pong": True} # Python の True → JSON では true
@app.get("/info")
def info():
return {"name": "my-api", "version": 1, "debug": False}app = FastAPI()は 1 ファイルに 1 つだけ。エンドポイントだけ増やしていく- 関数名は自由(URL と一致させる必要はない)。被らなければOK
- Python の
True/Falseは、レスポンス時に自動で JSON のtrue/falseに変換される
GET / → {"message":"Hello World"}
GET /ping → {"pong":true} ← 小文字の true
GET /info → {"name":"my-api","version":1,"debug":false}> エンドポイントを追加したいときは、新しい @app.get(...) + def 〜() を末尾に書き足すだけ。
まとめ
| やったこと | コード / コマンド |
|---|---|
| FastAPI のインスタンスを作った | app = FastAPI() |
| GET エンドポイントを定義した | @app.get("/") |
| 関数の return で JSON を返した | return {"message": "..."} |
| サーバーを起動した | uvicorn main:app --reload |
| Swagger UI で動作確認した | http://localhost:8000/docs |
ハンズオン
ch01-hello 演習ガイド
受講生向け演習問題集
採点の仕組み (読んでから始めてください)
採点テストは 「お題の通りに動くか」 を機械的にチェックします。
ドリルごとに 3つのタイプ があるので、各ドリル冒頭の 【タイプ】 を確認してください。
タイプ fill (穴埋め問題) — 文法・APIを知っているか
___(3個並んだアンダースコア) の空欄を埋める- 既存の構造は そのまま
- ロジック自由度: 低 (お題どおりに直す)
タイプ add (機能追加問題) — 既存コードに機能を足せるか
- 既存コードを残したまま、新しいエンドポイント/機能を 追加 する
- 実装方法は自由 (関数名・変数名・内部ロジックは好きに)
- ただしテストが要求する I/F (URL・HTTPメソッド・レスポンスのキー名) は守る
- 既存テストを壊さないこと
タイプ build (ゼロベース実装問題) — 仕様から実装を組み立てられるか
- ほぼ空の
main.pyから 自力で全部書く - ファイル構造・関数分割・命名・内部ロジック: 完全に自由
- 守るのはインターフェースだけ: URL・HTTP メソッド・レスポンス JSON 形式
- 一番ハードだが、実装力が一番つくタイプ
3タイプ共通で守ること
- ファイル名 (
main.py) は変えない tests/フォルダは触らない (採点ロジック)
このガイドのドリル一覧
| # | ドリル名 | タイトル | タイプ | 難易度 |
|---|---|---|---|---|
| 1 | 01-fill-decorator | @app.get デコレータ - 空欄を埋める | 🔧 穴埋め | ★ |
| 2 | 02-add-endpoint | @app.get を追加 - 新しいエンドポイントを追加する | ➕ 機能追加 | ★ |
| 3 | 03-change-response | レスポンスの dict を変える - 項目を追加する | ➕ 機能追加 | ★ |
| 4 | 04-build-hello-api | @app.get を複数並べる - Hello API を白紙から | 🛠️ ゼロ実装 | ★ |
> 詰まったら ヒント ページを開く。それでも分からなければ講師に質問。
ドリル 1: @app.get デコレータ - 空欄を埋める
ドリル名: 01-fill-decorator
> 🔧 【タイプ: 穴埋め問題】 ___ の部分を埋めて完成させてください。既存のコード構造は変えないこと。
問題
___ を埋めて GET /status → {"status": "ok"} を返すエンドポイントを完成させよ。
@app.___("/status")
def status():
return {"status": "ok"}確認方法
- ローカル:
uvicorn main:app --reload→http://localhost:8000/statusで{"status": "ok"}が返る
ドリル 1: ヒント
ドリル名: 01-fill-decorator
> ⚠️ 自力で考えてから読んでください
> GET / を定義したときのデコレータを思い出して。HTTP メソッドの名前が小文字でそのまま使われている。
ドリル 2: @app.get を追加 - 新しいエンドポイントを追加する
ドリル名: 02-add-endpoint
> ➕ 【タイプ: 機能追加問題】 既存コードを残したまま新しい機能を追加してください。実装は自由ですが、テストが要求する I/F・表示テキストは守ること。
問題
/greeting にアクセスしたとき、以下のJSONを返すエンドポイントを追加せよ。
入力
GET /greeting (パラメータなし)
出力例
{"message": "こんにちは"}確認方法
- Swagger UI →
GET /greeting→ Try it out → Execute で上記が返ること
守るべきこと
- 既存の
GET /({"message": "Hello World"}) を壊さないこと
★ 余裕がある人向け: 拡張課題
このドリルが PASS したら、以下の発展課題に挑戦してみてください (採点はなし、自由演習)。
/greetingにクエリパラメータnameを受け取れるようにして、?name=Taroのときは{"message": "こんにちは、Taro"}を返すようにする/greeting/{lang}を追加して、langにja/en/frを渡すと言語ごとの挨拶文を返すようにする (それ以外は 400)print()でリクエストごとに簡易ログを標準出力に出してみる
採点ロジックは元のテストのままです。拡張部分を実装してもテストは PASS のまま、自分の力試しになります。
ドリル 2: ヒント
ドリル名: 02-add-endpoint
> ⚠️ 自力で考えてから読んでください
> GET / を定義したときと同じ考え方で、パスの部分だけ変えると別のURLになる。
ドリル 3: レスポンスの dict を変える - 項目を追加する
ドリル名: 03-change-response
> ➕ 【タイプ: 機能追加問題】 既存コードを残したまま新しい機能を追加してください。実装は自由ですが、テストが要求する I/F・表示テキストは守ること。
問題
GET / のレスポンスを以下の条件に変えよ。
messageの値を自分の名前を使った挨拶文にする (例:"Hello, Taro")versionというキーを追加して整数1を返す
出力例
{"message": "Hello, Taro", "version": 1}※ message の値は自分の名前に合わせて変えてよい。
確認方法
- ローカル:
http://localhost:8000→ 上記の形式が返ること
採点ポイント
messageキーが存在し、文字列で"Hello, "から始まるversionキーが存在し、整数1
★ 余裕がある人向け: 拡張課題
このドリルが PASS したら、以下の発展課題に挑戦してみてください (採点はなし、自由演習)。
- レスポンスに
timestampキーを追加して、現在時刻を ISO 8601 形式の文字列で返す (datetime.now().isoformat()) versionの値を環境変数APP_VERSIONから読み取れるようにする (未設定なら1)/infoという別エンドポイントを追加して、Python のバージョンや起動時刻などのメタ情報を返してみる
採点ロジックは元のテストのままです。拡張部分を実装してもテストは PASS のまま、自分の力試しになります。
ドリル 3: ヒント
ドリル名: 03-change-response
> ⚠️ 自力で考えてから読んでください
> Python の dict に複数のキーを持たせる方法を思い出して。return に渡す dict を変えれば返ってくる JSON が変わる。
ドリル 4: @app.get を複数並べる - Hello API を白紙から
ドリル名: 04-build-hello-api
> 🛠️ 【タイプ: ゼロベース実装問題】 ほぼ空の main.py から仕様を読んで自力で実装してください。ファイル構造・関数名・内部ロジックは完全に自由。ただしテストが叩く インターフェース (URL / HTTP メソッド / レスポンス形式) は仕様どおりに揃えること。
問題
複数エンドポイントを持つ最小 API を main.py に 白紙から 実装してください。
仕様
| メソッド | URL | レスポンス |
|---|---|---|
| GET | / | {"message": "Hello, World"} |
| GET | /ping | {"pong": true} |
| GET | /info | {"app": "hello-api", "version": "1.0"} |
守る (テストが見ている)
- 上記 3 つのエンドポイントが GET で叩けて、指定の JSON を返す
自由に設計できる例
- 関数名は自由 (
root/home/index等) - import の書き方も自由
- 1ファイル
main.pyに書く
確認方法
- 起動.bat / 起動.sh をダブルクリック → ブラウザに結果表示
> 本章の総まとめ: 「@app.get() を自力で 3 つ書く」 が目標です。
このドリルで学ぶこと
| 学習要素 | 学習資料との対応 |
|---|---|
複数の @app.get() を並べて書く | ch01 slide「複数のエンドポイントを並べる」 |
Python の True が JSON の true になる | ch01 slide「複数のエンドポイントを並べる」 |
| fill drill では1個ずつ書いた構造を「自力で3個並べる」体験 | ch01 fill/add drill の発展 |
このドリルは ch01-hello の 総まとめ。03-change-response までで学んだ要素を、白紙から 複数並べて書ける 状態に到達できるかをテストします。
ドリル 4: ヒント
ドリル名: 04-build-hello-api
> ⚠️ 自力で考えてから読んでください
各エンドポイントは @app.get("/...") デコレータ + 関数で書ける。
@app.get("/")
def root():
return {"message": "Hello, World"}同じパターンで /ping と /info を追加するだけ。
考えてみよう
既定では正解・不正解の判定はしません。自分のペースで「答えを見る」を。採点してほしい場合だけ「採点してほしい」を押してください。
ch01-hello 演習ガイド
受講生向け演習問題集
採点の仕組み (読んでから始めてください)
採点テストは 「お題の通りに動くか」 を機械的にチェックします。
ドリルごとに 3つのタイプ があるので、各ドリル冒頭の 【タイプ】 を確認してください。
タイプ fill (穴埋め問題) — 文法・APIを知っているか
___(3個並んだアンダースコア) の空欄を埋める- 既存の構造は そのまま
- ロジック自由度: 低 (お題どおりに直す)
タイプ add (機能追加問題) — 既存コードに機能を足せるか
- 既存コードを残したまま、新しいエンドポイント/機能を 追加 する
- 実装方法は自由 (関数名・変数名・内部ロジックは好きに)
- ただしテストが要求する I/F (URL・HTTPメソッド・レスポンスのキー名) は守る
- 既存テストを壊さないこと
タイプ build (ゼロベース実装問題) — 仕様から実装を組み立てられるか
- ほぼ空の
main.pyから 自力で全部書く - ファイル構造・関数分割・命名・内部ロジック: 完全に自由
- 守るのはインターフェースだけ: URL・HTTP メソッド・レスポンス JSON 形式
- 一番ハードだが、実装力が一番つくタイプ
3タイプ共通で守ること
- ファイル名 (
main.py) は変えない tests/フォルダは触らない (採点ロジック)
このガイドのドリル一覧
| # | ドリル名 | タイトル | タイプ | 難易度 |
|---|---|---|---|---|
| 1 | 01-fill-decorator | @app.get デコレータ - 空欄を埋める | 🔧 穴埋め | ★ |
| 2 | 02-add-endpoint | @app.get を追加 - 新しいエンドポイントを追加する | ➕ 機能追加 | ★ |
| 3 | 03-change-response | レスポンスの dict を変える - 項目を追加する | ➕ 機能追加 | ★ |
| 4 | 04-build-hello-api | @app.get を複数並べる - Hello API を白紙から | 🛠️ ゼロ実装 | ★ |
> 詰まったら ヒント ページを開く。それでも分からなければ講師に質問。
ドリル 1: @app.get デコレータ - 空欄を埋める
ドリル名: 01-fill-decorator
> 🔧 【タイプ: 穴埋め問題】 ___ の部分を埋めて完成させてください。既存のコード構造は変えないこと。
問題
___ を埋めて GET /status → {"status": "ok"} を返すエンドポイントを完成させよ。
@app.___("/status")
def status():
return {"status": "ok"}確認方法
- ローカル:
uvicorn main:app --reload→http://localhost:8000/statusで{"status": "ok"}が返る
ドリル 1: ヒント
ドリル名: 01-fill-decorator
> ⚠️ 自力で考えてから読んでください
> GET / を定義したときのデコレータを思い出して。HTTP メソッドの名前が小文字でそのまま使われている。
ドリル 2: @app.get を追加 - 新しいエンドポイントを追加する
ドリル名: 02-add-endpoint
> ➕ 【タイプ: 機能追加問題】 既存コードを残したまま新しい機能を追加してください。実装は自由ですが、テストが要求する I/F・表示テキストは守ること。
問題
/greeting にアクセスしたとき、以下のJSONを返すエンドポイントを追加せよ。
入力
GET /greeting (パラメータなし)
出力例
{"message": "こんにちは"}確認方法
- Swagger UI →
GET /greeting→ Try it out → Execute で上記が返ること
守るべきこと
- 既存の
GET /({"message": "Hello World"}) を壊さないこと
★ 余裕がある人向け: 拡張課題
このドリルが PASS したら、以下の発展課題に挑戦してみてください (採点はなし、自由演習)。
/greetingにクエリパラメータnameを受け取れるようにして、?name=Taroのときは{"message": "こんにちは、Taro"}を返すようにする/greeting/{lang}を追加して、langにja/en/frを渡すと言語ごとの挨拶文を返すようにする (それ以外は 400)print()でリクエストごとに簡易ログを標準出力に出してみる
採点ロジックは元のテストのままです。拡張部分を実装してもテストは PASS のまま、自分の力試しになります。
ドリル 2: ヒント
ドリル名: 02-add-endpoint
> ⚠️ 自力で考えてから読んでください
> GET / を定義したときと同じ考え方で、パスの部分だけ変えると別のURLになる。
ドリル 3: レスポンスの dict を変える - 項目を追加する
ドリル名: 03-change-response
> ➕ 【タイプ: 機能追加問題】 既存コードを残したまま新しい機能を追加してください。実装は自由ですが、テストが要求する I/F・表示テキストは守ること。
問題
GET / のレスポンスを以下の条件に変えよ。
messageの値を自分の名前を使った挨拶文にする (例:"Hello, Taro")versionというキーを追加して整数1を返す
出力例
{"message": "Hello, Taro", "version": 1}※ message の値は自分の名前に合わせて変えてよい。
確認方法
- ローカル:
http://localhost:8000→ 上記の形式が返ること
採点ポイント
messageキーが存在し、文字列で"Hello, "から始まるversionキーが存在し、整数1
★ 余裕がある人向け: 拡張課題
このドリルが PASS したら、以下の発展課題に挑戦してみてください (採点はなし、自由演習)。
- レスポンスに
timestampキーを追加して、現在時刻を ISO 8601 形式の文字列で返す (datetime.now().isoformat()) versionの値を環境変数APP_VERSIONから読み取れるようにする (未設定なら1)/infoという別エンドポイントを追加して、Python のバージョンや起動時刻などのメタ情報を返してみる
採点ロジックは元のテストのままです。拡張部分を実装してもテストは PASS のまま、自分の力試しになります。
ドリル 3: ヒント
ドリル名: 03-change-response
> ⚠️ 自力で考えてから読んでください
> Python の dict に複数のキーを持たせる方法を思い出して。return に渡す dict を変えれば返ってくる JSON が変わる。
ドリル 4: @app.get を複数並べる - Hello API を白紙から
ドリル名: 04-build-hello-api
> 🛠️ 【タイプ: ゼロベース実装問題】 ほぼ空の main.py から仕様を読んで自力で実装してください。ファイル構造・関数名・内部ロジックは完全に自由。ただしテストが叩く インターフェース (URL / HTTP メソッド / レスポンス形式) は仕様どおりに揃えること。
問題
複数エンドポイントを持つ最小 API を main.py に 白紙から 実装してください。
仕様
| メソッド | URL | レスポンス |
|---|---|---|
| GET | / | {"message": "Hello, World"} |
| GET | /ping | {"pong": true} |
| GET | /info | {"app": "hello-api", "version": "1.0"} |
守る (テストが見ている)
- 上記 3 つのエンドポイントが GET で叩けて、指定の JSON を返す
自由に設計できる例
- 関数名は自由 (
root/home/index等) - import の書き方も自由
- 1ファイル
main.pyに書く
確認方法
- 起動.bat / 起動.sh をダブルクリック → ブラウザに結果表示
> 本章の総まとめ: 「@app.get() を自力で 3 つ書く」 が目標です。
このドリルで学ぶこと
| 学習要素 | 学習資料との対応 |
|---|---|
複数の @app.get() を並べて書く | ch01 slide「複数のエンドポイントを並べる」 |
Python の True が JSON の true になる | ch01 slide「複数のエンドポイントを並べる」 |
| fill drill では1個ずつ書いた構造を「自力で3個並べる」体験 | ch01 fill/add drill の発展 |
このドリルは ch01-hello の 総まとめ。03-change-response までで学んだ要素を、白紙から 複数並べて書ける 状態に到達できるかをテストします。
ドリル 4: ヒント
ドリル名: 04-build-hello-api
> ⚠️ 自力で考えてから読んでください
各エンドポイントは @app.get("/...") デコレータ + 関数で書ける。
@app.get("/")
def root():
return {"message": "Hello, World"}同じパターンで /ping と /info を追加するだけ。
ch01-hello 演習解説
⚠️ 自力でドリルを解いてから読んでください
ドリル 1: @app.get デコレータ - 空欄を埋める — 模範解答
ドリル名: 01-fill-decorator
from fastapi import FastAPI
app = FastAPI()
@app.get("/status")
def status():
return {"status": "ok"}ドリル 1: @app.get デコレータ - 空欄を埋める — 解説
ドリル名: 01-fill-decorator
@app.get("/status")
def status():
return {"status": "ok"}ポイント
@app.get()のgetは HTTP GET に対応- POST なら
@app.post()、PUT なら@app.put() - デコレータの引数 (
"/status") がそのまま URL のパスになる
ドリル 2: @app.get を追加 - 新しいエンドポイントを追加する — 模範解答
ドリル名: 02-add-endpoint
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def hello():
return {"message": "Hello World"}
@app.get("/greeting")
def greeting():
return {"message": "こんにちは"}ドリル 2: @app.get を追加 - 新しいエンドポイントを追加する — 解説
ドリル名: 02-add-endpoint
@app.get("/greeting")
def greeting():
return {"message": "こんにちは"}ポイント
@app.get()に渡すパスがそのまま URL になる- 関数名は URL と一致していなくてよい (ただし可読性のため近い名前を推奨)
- 既存の
@app.get("/")の後に追加するだけで、Swagger UI にも自動表示される
ドリル 3: レスポンスの dict を変える - 項目を追加する — 模範解答
ドリル名: 03-change-response
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def hello():
return {"message": "Hello, Taro", "version": 1}ドリル 3: レスポンスの dict を変える - 項目を追加する — 解説
ドリル名: 03-change-response
@app.get("/")
def hello():
return {"message": "Hello, Taro", "version": 1}ポイント
returnに渡した dict のキーと値がそのまま JSON になる- キーの追加・変更は dict を書き直すだけでよい
- 型情報も保持される (
versionはintのまま1として JSON 化される)
ドリル 4: @app.get を複数並べる - Hello API を白紙から — 模範解答
ドリル名: 04-build-hello-api
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def root():
return {"message": "Hello, World"}
@app.get("/ping")
def ping():
return {"pong": True}
@app.get("/info")
def info():
return {"app": "hello-api", "version": "1.0"}ドリル 4: @app.get を複数並べる - Hello API を白紙から — 解説
ドリル名: 04-build-hello-api
FastAPI で複数エンドポイントを書く時の基本パターン:
@app.get("/<path>")
def <function_name>():
return <dict_to_be_serialized_as_json>- 関数名は URL と一致しなくて OK (好きな名前)
- 戻り値の dict はそのまま JSON に変換される (FastAPI の標準動作)
- True/False は Python の真偽値、JSON の
true/falseに変換される