3日目のゴール
3日目のテーマは
「requests を“使い回せる道具”として設計し、複数のAPIを扱えるようになる」 ことです。
1日目で「とりあえず叩けるようになり」、
2日目で「エラーに強い書き方」を学びました。
3日目では一歩進んで、
同じパターンで別のAPIも叩けるようにする
GETだけでなく、POSTもイメージできるようにする
「APIクライアント関数(またはクラス)」という考え方を持つ
ここまで行けると、
「APIを1個だけ触れる人」から
「APIを道具として横展開できる人」に変わります。
「APIのパターン」を見抜く
どのAPIも、やっていることはだいたい同じ
APIのドキュメントを見ると、
いろんなURLやパラメータが出てきて、
最初は圧倒されがちです。
でも、冷静に分解すると、
やっていることはほぼ同じです。
URLがある
HTTPメソッド(GET / POST / PUT / DELETE など)がある
必要ならクエリパラメータやボディがある
必要ならヘッダー(APIキーなど)がある
返ってくるのはだいたいJSON
1日目・2日目でやったことは、
このうちの「GET+JSON」の部分です。
3日目では、
この「型」を意識しながら、
別のAPIにも同じパターンを当てはめていきます。
複数のエンドポイントを扱うイメージ
同じサービスの中に「いろんな窓口」がある
例えば、1日目・2日目で使ったhttps://jsonplaceholder.typicode.com には、
こんなエンドポイントがあります。
/todos/posts/users
それぞれ、
TODOの情報
ブログ記事っぽい情報
ユーザー情報
を返してくれます。
URLだけ変えて、
同じ get_json 関数を使えば、
どれも同じように扱えます。
import requests
def get_json(url, params=None, timeout=5.0):
try:
response = requests.get(url, params=params, timeout=timeout)
except requests.exceptions.Timeout:
print("タイムアウトしました。")
return None
except requests.exceptions.RequestException as e:
print("通信エラー:", e)
return None
if response.status_code != 200:
print("エラー応答です。ステータスコード:", response.status_code)
return None
try:
return response.json()
except ValueError:
print("JSONとして解釈できませんでした。")
return None
Pythonこの「共通の入口」を持っておくと、
あとはURLとパラメータを変えるだけで、
いろんなAPIを触れるようになります。
例題1:ユーザー一覧APIを叩いてみる
「別のエンドポイントでも同じ型で書ける」ことを体感する
ユーザー一覧を取得するAPIを叩いてみます。
def fetch_users():
url = "https://jsonplaceholder.typicode.com/users"
data = get_json(url)
if data is None:
print("ユーザー一覧の取得に失敗しました。")
return
print(f"ユーザーは {len(data)} 人います。")
for user in data:
print(f"- {user['id']}: {user['name']} ({user['email']})")
Pythonここで注目してほしいのは、
get_json の使い方は、TODOのときとまったく同じ
変わっているのは URL と、
「返ってきたデータの中から何を表示するか」だけ
という点です。
APIが変わっても、
「叩き方の型」は変わりません。
例題2:記事一覧APIを叩いてみる
同じパターンで別のデータ構造を読む
今度は /posts を叩いてみます。
def fetch_posts(limit=5):
url = "https://jsonplaceholder.typicode.com/posts"
data = get_json(url)
if data is None:
print("記事一覧の取得に失敗しました。")
return
print(f"記事は全部で {len(data)} 件あります。")
print(f"最初の {limit} 件を表示します。")
for post in data[:limit]:
print("-----")
print(f"ID: {post['id']}")
print(f"タイトル: {post['title']}")
print(f"本文: {post['body'][:50]}...")
Pythonここでも、
URLが違う
返ってくるJSONのキーが違う
だけで、
「叩き方の型」は同じです。
この感覚がつかめると、
APIドキュメントを見たときに、
「URLとパラメータと返り値の形だけ分かれば、あとはいつものパターンで書ける」
という安心感が生まれます。
POSTリクエストのイメージを掴む
「データを送る」側のAPI
ここまでの GET は、
「サーバーからデータをもらう」リクエストでした。
POST は、
「サーバーにデータを送る」リクエストです。
例えば、「新しい記事を作成するAPI」があったとします。
POST /posts
ボディに title や body を送る
成功すると、作成された記事の情報が返ってくる
requests では、data や json 引数を使って、
送るデータを指定します。
import requests
url = "https://jsonplaceholder.typicode.com/posts"
payload = {
"title": "テスト投稿",
"body": "これはテスト投稿の本文です。",
"userId": 1,
}
response = requests.post(url, json=payload, timeout=5.0)
print("ステータスコード:", response.status_code)
print("レスポンス:", response.json())
Pythonここでの重要ポイントを深掘りします。
requests.post を使うと、HTTPメソッドがPOSTになるjson=payload と書くと、
payload を JSON としてボディに入れて送ってくれる
サーバー側が受け取って、何らかの処理をして、結果を返してくる
実際のサービスでは、
「本当にデータが作成される」ので、
テスト環境やドキュメントをよく読む必要があります。
3日目では、
「GETはもらう、POSTは送る」
というイメージが持てれば十分です。
GETとPOSTをまとめて扱う「APIクライアント関数」
メソッドを引数にしてしまう
2日目で作った get_json を、
少しだけ汎用的にしてみます。
import requests
def request_json(method, url, params=None, json_body=None, headers=None, timeout=5.0):
try:
response = requests.request(
method=method,
url=url,
params=params,
json=json_body,
headers=headers,
timeout=timeout,
)
except requests.exceptions.Timeout:
print("タイムアウトしました。")
return None
except requests.exceptions.RequestException as e:
print("通信エラー:", e)
return None
if not (200 <= response.status_code < 300):
print("エラー応答です。ステータスコード:", response.status_code)
return None
try:
return response.json()
except ValueError:
print("JSONとして解釈できませんでした。")
return None
Pythonここでのポイントは、
requests.request に method を渡すことで、
GETでもPOSTでも同じ関数で扱えるようにしていることjson_body を json= に渡していること
ステータスコードを「200〜299ならOK」としていること
です。
これを使うと、
GETもPOSTも同じ型で書けます。
例題3:GETとPOSTを同じ関数で使う
同じAPIクライアントで、読み取りと作成を行う
def get_todo(todo_id):
url = f"https://jsonplaceholder.typicode.com/todos/{todo_id}"
data = request_json("GET", url)
if data is None:
print("TODOの取得に失敗しました。")
return
print("ID:", data["id"])
print("タイトル:", data["title"])
print("完了フラグ:", data["completed"])
def create_post(title, body, user_id):
url = "https://jsonplaceholder.typicode.com/posts"
payload = {
"title": title,
"body": body,
"userId": user_id,
}
data = request_json("POST", url, json_body=payload)
if data is None:
print("投稿の作成に失敗しました。")
return
print("作成された投稿:")
print("ID:", data.get("id"))
print("タイトル:", data.get("title"))
print("本文:", data.get("body"))
Pythonここで見てほしいのは、
request_json("GET", ...)request_json("POST", ...)
という形で、
メソッドだけ変えて同じ関数を使っていることです。
これができると、
APIの種類が増えても、
「叩き方の型」は変わりません。
3日目のミニアプリ:APIメニュー付きコンソールツール
仕様を言葉で整理する
コンソール上で動く「APIお試しツール」を作ります。
メニューを表示する
1を選ぶと TODO を1件取得
2を選ぶと ユーザー一覧を取得
3を選ぶと 記事を数件取得
0で終了
APIの叩き方は全部「同じ型」で書きます。
コード全体
import requests
def request_json(method, url, params=None, json_body=None, timeout=5.0):
try:
response = requests.request(
method=method,
url=url,
params=params,
json=json_body,
timeout=timeout,
)
except requests.exceptions.Timeout:
print("タイムアウトしました。")
return None
except requests.exceptions.RequestException as e:
print("通信エラー:", e)
return None
if not (200 <= response.status_code < 300):
print("エラー応答です。ステータスコード:", response.status_code)
return None
try:
return response.json()
except ValueError:
print("JSONとして解釈できませんでした。")
return None
def fetch_todo():
todo_id_str = input("TODOのIDを入力してください(例: 1): ").strip()
if not todo_id_str.isdigit():
print("数字を入力してください。")
return
todo_id = int(todo_id_str)
url = f"https://jsonplaceholder.typicode.com/todos/{todo_id}"
data = request_json("GET", url)
if data is None:
print("TODOの取得に失敗しました。")
return
print("----- TODO -----")
print("ID:", data["id"])
print("タイトル:", data["title"])
print("完了フラグ:", data["completed"])
def fetch_users():
url = "https://jsonplaceholder.typicode.com/users"
data = request_json("GET", url)
if data is None:
print("ユーザー一覧の取得に失敗しました。")
return
print("----- ユーザー一覧 -----")
for user in data:
print(f"{user['id']}: {user['name']} ({user['email']})")
def fetch_posts():
url = "https://jsonplaceholder.typicode.com/posts"
data = request_json("GET", url)
if data is None:
print("記事一覧の取得に失敗しました。")
return
print("----- 記事(最初の5件) -----")
for post in data[:5]:
print("ID:", post["id"])
print("タイトル:", post["title"])
print("本文:", post["body"][:50], "...")
print("-----")
def main():
while True:
print()
print("APIお試しツール")
print("1: TODOを1件取得")
print("2: ユーザー一覧を取得")
print("3: 記事を5件取得")
print("0: 終了")
choice = input("番号を選んでください: ").strip()
if choice == "1":
fetch_todo()
elif choice == "2":
fetch_users()
elif choice == "3":
fetch_posts()
elif choice == "0":
print("終了します。")
break
else:
print("不正な入力です。")
if __name__ == "__main__":
main()
Pythonここには、3日目で押さえたい要素が全部入っています。
共通の request_json で、
GETリクエストとエラー処理を一元管理している。
各機能(TODO・ユーザー・記事)は、
「URLと表示ロジック」だけを書けばよくなっている。
3日目で絶対に押さえてほしい本質
「APIの叩き方を“型”として持つ」と世界が一気に楽になる
今日いちばん大事なのは、
APIごとに毎回ゼロから書かない
自分なりの「APIクライアント関数(request_json)」を持つ
URL・パラメータ・メソッド・表示ロジックだけを差し替える
という発想です。
技術的なキーワードをまとめると、
複数エンドポイントを同じ関数で扱うrequests.request(method=...) でGET/POSTを統一する
JSONレスポンスを辞書・リストとして扱うのはどれも同じ
「URLと返り値の形が分かれば怖くない」状態になる
ここまで来たあなたは、
もう「APIを触れる人」ではなく、
「APIを設計して使い回せる人」 の入り口に立っています。
4日目以降は、
ここで作ったAPIクライアントを
tkinter のボタンイベントと組み合わせて、
「ボタンを押したらAPIを叩いて、結果を画面に表示する」
という、いよいよ“GUI付きAPIアプリ”に進んでいきましょう。


