2日目のゴール
2日目のテーマは
「requests を“ちゃんとした道具”として扱えるようになる」 ことです。
1日目は、
URLにアクセスする
ステータスコードを見る
JSONを response.json() で辞書として扱う
ここまで行きました。
2日目では一歩進んで、
タイムアウトや通信エラーに備えるtry / except で「落ちないAPIコード」にする
クエリパラメータやヘッダーを整理して書く
「APIを叩く関数」を自分で設計する
という、「実戦で使える requests の書き方」に近づいていきます。
なぜエラー処理が必要なのか
APIは「こっちの都合」では動いてくれない
ローカルの計算なら、
自分のPCの中だけで完結します。
でも、APIは違います。
相手のサーバーが落ちているかもしれない
ネットワークが不安定かもしれない
レスポンスが返ってくるまで異常に時間がかかるかもしれない
URLやパラメータを自分が間違えているかもしれない
つまり、
「うまくいかない可能性」が常にある世界 です。
だからこそ、
ステータスコードを確認する
タイムアウトを設定する
例外(Exception)をキャッチする
という「守りのコード」が大事になります。
タイムアウトを付けるという発想
いつまでも待ち続けるコードは危険
何も指定しない requests.get(url) は、
基本的に「レスポンスが返ってくるまで待ち続ける」動きになります。
もしサーバーが固まっていたら?
もしネットワークが詰まっていたら?
あなたのプログラムも、
ずっと固まったままになります。
そこで使うのが timeout です。
import requests
url = "https://jsonplaceholder.typicode.com/todos/1"
response = requests.get(url, timeout=5.0)
Pythonこの timeout=5.0 は、
「最大5秒だけ待つ。5秒経っても返ってこなかったらエラーにする」
という意味です。
ここで重要なのは、
タイムアウトは「秒数」で指定する
短すぎるとすぐエラーになる
長すぎると固まっているのと変わらない
というバランス感覚です。
とりあえず、
「APIを叩くときは timeout を付ける」
という習慣だけ、2日目で身につけておきましょう。
requests の例外をちゃんと受け止める
失敗したときに「落ちないコード」にする
timeout を付けると、
タイムアウトしたときに requests.exceptions.Timeout という例外が発生します。
また、ネットワークの問題などでrequests.exceptions.RequestException という例外が出ることもあります。
これらを try / except で受け止めることで、
プログラム全体が落ちずに「エラーメッセージを出して終わる」
という、まともな振る舞いになります。
import requests
def fetch_todo(todo_id):
url = f"https://jsonplaceholder.typicode.com/todos/{todo_id}"
try:
response = requests.get(url, timeout=5.0)
except requests.exceptions.Timeout:
print("タイムアウトしました。サーバーの応答が遅いようです。")
return
except requests.exceptions.RequestException as e:
print("通信エラーが発生しました。詳細:", e)
return
if response.status_code != 200:
print("取得に失敗しました。ステータスコード:", response.status_code)
return
try:
data = response.json()
except ValueError:
print("レスポンスをJSONとして解釈できませんでした。")
return
print("ID:", data["id"])
print("タイトル:", data["title"])
print("完了フラグ:", data["completed"])
Pythonここでの重要ポイントを深掘りします。
try: の中に「失敗するかもしれない処理」を入れるexcept requests.exceptions.Timeout: でタイムアウト専用の処理を書くexcept requests.exceptions.RequestException as e: でその他の通信エラーをまとめて受けるresponse.json() も失敗する可能性があるので、別の try / except で囲む
これで、
ネットワークエラー
タイムアウト
ステータスコード異常
JSON解釈エラー
といった「よくある失敗パターン」を、
全部「落ちない形」で処理できるようになります。
「APIを叩く関数」を1つの型として覚える
何度も使える“テンプレート”を作る
2日目で、ぜひ頭に入れてほしいのが
「API取得関数の型」 です。
例えば、こんな形です。
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とパラメータを受け取る
GETリクエストを送る
エラーを全部受け止める
成功したら JSON を辞書やリストとして返す
失敗したら None を返す
という「型」になっています。
これを使うと、
APIを叩く側のコードがとてもシンプルになります。
def fetch_todo(todo_id):
url = f"https://jsonplaceholder.typicode.com/todos/{todo_id}"
data = get_json(url)
if data is None:
print("TODOの取得に失敗しました。")
return
print("ID:", data["id"])
print("タイトル:", data["title"])
print("完了フラグ:", data["completed"])
Pythonここでの本質は、
「エラー処理を毎回ベタ書きしない」
「API取得の共通処理を1か所にまとめる」
という設計の考え方です。
クエリパラメータを「辞書」で渡すメリット
URLを文字列でゴリゴリ書かない
1日目でも少し触れましたが、
クエリパラメータは params で渡すのが基本です。
import requests
url = "https://jsonplaceholder.typicode.com/todos"
params = {"userId": 1}
response = requests.get(url, params=params, timeout=5.0)
Pythonこれを、さっきの get_json に組み合わせるとこうなります。
def fetch_todos_by_user(user_id):
url = "https://jsonplaceholder.typicode.com/todos"
params = {"userId": user_id}
data = get_json(url, params=params)
if data is None:
print("TODO一覧の取得に失敗しました。")
return
print(f"userId={user_id} のTODOは {len(data)} 件あります。")
for item in data[:5]:
print("-", item["id"], item["title"])
Pythonここでの大事なポイントは、
URL文字列を "https://.../todos?userId=1" のように自分で組み立てないparams に辞書で渡すことで、
requests が正しくエンコードしてくれる
ということです。
パラメータが増えれば増えるほど、params を使うメリットは大きくなります。
ヘッダーを付けるという発想
「名札」や「鍵」を一緒に送るイメージ
多くのAPIは、
「APIキー」や「トークン」をヘッダーに付けて送る必要があります。
例えば、こんなイメージです。
headers = {
"Authorization": "Bearer xxxxxxxx",
"Accept": "application/json",
}
Pythonrequests.get に headers を渡すと、
HTTPリクエストのヘッダーとして送ってくれます。
response = requests.get(url, headers=headers, timeout=5.0)
Python2日目では、
実際のAPIキーを使わなくてもいいので、
「ヘッダー = リクエストに付ける追加情報」
というイメージだけ持っておいてください。
get_json を少し拡張すると、こうなります。
def get_json(url, params=None, headers=None, timeout=5.0):
try:
response = requests.get(url, params=params, headers=headers, 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これで、
APIキーが必要なAPIにも、そのまま対応できる形になります。
2日目のミニアプリ:ユーザーID別TODO一覧ビューア
仕様
ユーザーIDを入力する
そのユーザーのTODO一覧をAPIから取得する
最初の数件だけタイトルを表示する
エラーが起きても落ちずにメッセージを出す
コンソール版で、「エラーに強いAPIクライアント」の感覚を掴みます。
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
def fetch_todos_by_user(user_id):
url = "https://jsonplaceholder.typicode.com/todos"
params = {"userId": user_id}
data = get_json(url, params=params)
if data is None:
print("TODO一覧の取得に失敗しました。")
return
print(f"userId={user_id} のTODOは {len(data)} 件あります。")
print("最初の5件を表示します。")
for item in data[:5]:
print(f"- [{item['id']}] {item['title']} (完了: {item['completed']})")
def main():
print("ユーザーID別 TODO 一覧ビューア")
user_id_str = input("ユーザーIDを入力してください(例: 1): ").strip()
if not user_id_str.isdigit():
print("数字を入力してください。")
return
user_id = int(user_id_str)
fetch_todos_by_user(user_id)
if __name__ == "__main__":
main()
Pythonここには、2日目で押さえたい要素が詰まっています。
get_json という共通関数で、
タイムアウト・通信エラー・ステータスコード・JSONエラーをまとめて処理している。
APIを使う側(fetch_todos_by_user)は、
「URLとパラメータを渡して、返ってきたデータを使う」ことだけに集中できている。
2日目で絶対に押さえてほしい本質
「APIは失敗する前提で書く」ことが“中級”の入り口
今日いちばん大事なのは、
APIはいつでも成功するわけではない
だから、失敗したときの振る舞いを最初から決めておく
そのために、timeout と try / except をセットで使う
という感覚です。
技術的なキーワードをまとめると、
requests.get(url, timeout=秒数) で「待ち時間の上限」を決めるrequests.exceptions.Timeout や RequestException を except で受けるresponse.status_code を見て 200 以外を弾くresponse.json() も失敗することがあるので try / except で囲む
API取得処理を get_json のような共通関数にまとめる
ここまでできると、
あなたのAPIコードはもう「初心者の一発芸」ではなく、
「壊れにくい道具」 になっています。
3日目以降は、
このAPI取得ロジックを tkinter のボタンイベントと組み合わせて、
「ボタンを押したらAPIからデータを取ってきて、画面に表示する」
という、いよいよ“アプリらしいAPIクライアント”に進んでいきます。
まずは今日の get_json を、自分の「APIテンプレ」として
コピペしながら育てていってください。
ここを自分の型にできたら、APIの世界は一気に楽になります。


