ふくふくHukuhuku Inc.
EP.01Data Fetch 9分公開: 2026-09-02

その API を叩く前に決めておく5つのこと

動くコードはすぐ書けます。つらくなるのは、動いたあとです。タイムアウト・再試行・名乗り・並列度・保存先。この5つを最初に決めておくと、後から書き直す量が激減します。

#API#設計#Python
執筆 / 監修
松尾 亮合同会社ふくふく 代表社員

データ基盤・データパイプライン構築 / BI / 生成 AI 活用支援を専門とするエンジニア (28 年)。 本記事は AI 利用ポリシーに基づき、生成 AI の補助で執筆 → 人間が監修・編集して公開しています。

プロフィール詳細
シェア

データを取ってくるコードは、最初の1行が一番簡単です。`requests.get(url).json()` と書けば、たいていのデータは手に入ります。問題はそのあとで、相手が落ちていたとき、件数が想定の100倍あったとき、同じものを明日また取りたくなったときに、最初の1行では足りなくなります。

後から足すのは大変です。取得部分は他の処理から呼ばれるので、あとで引数が増えたり例外の種類が変わったりすると、呼び出し側も全部直すことになります。最初に決めておけば済む話が、動いてしまったあとだと数日の手戻りになる。この回では、書き始める前に決めておく5つを挙げます。

1. タイムアウトを必ず書く

が返ってこないまま、いつまでも待ち続けるのが、いちばん厄介な失敗です。エラーで落ちてくれれば気づけますが、待ち続けるコードは黙って止まっているだけなので、翌朝まで誰も気づきません。

Python の requests は、タイムアウトを指定しないと無期限で待ちます。これは既定値としては危険な側に倒れているので、書く側が毎回指定する必要があります。接続までの待ちと、応答本体の待ちは分けて指定できます。

接続 5 秒・読み取り 30 秒。数字に絶対の正解はないが、無指定よりはるかにまし
Python
import requests
# (接続タイムアウト, 読み取りタイムアウト) の順resp = requests.get(    "https://example.com/api/items",    timeout=(5, 30),    headers={"User-Agent": "hukuhuku-data-fetch/1.0 (+https://hukuhuku.co.jp)"},)resp.raise_for_status()   # 4xx / 5xx をここで例外にするdata = resp.json()
raise_for_status() を忘れない

requests は 404 でも 500 でも例外を投げません。`resp.json()` がたまたま成功して、エラーメッセージの JSON をデータとして処理してしまうことがあります。取得した瞬間に status を確認するのを習慣にしてください。

2. どの失敗をやり直すかを決める

通信は一定の確率で失敗します。を組み込むこと自体は当然として、やり直してよい失敗と、やり直しても無駄な失敗を分けておく必要があります。ここを分けずに全部やり直すと、認証が間違っているだけなのに何十回も叩き続けることになります。

ステータスコードごとの扱い
コード意味やり直す?
429要求が多すぎるする。待ち時間を空けて
500 / 502 / 503 / 504サーバ側の異常する
408サーバ側でのタイムアウトする
401 / 403認証・権限の問題しない。設定を直す
404存在しないしない。URL を疑う
400 / 422要求の内容が不正しない。パラメータを直す

待ち方も決めておきます。 — 1秒、2秒、4秒と間隔を倍にしていく方式が一般的です。ここに少しゆらぎを足すのが定石で、理由は次の回で扱います。

3. 名乗りを決める

を既定のままにしないでください。Python の requests は `python-requests/2.x` と名乗りますが、これを一律で拒否している配信元があります。逆に、公的機関の では「問い合わせ先が分かる名乗り」を求めていることがあります。

組織名と連絡先を含めておくと、相手が困ったときに連絡できます。過剰な取得をしてしまったときに、いきなり遮断されるかわりに一報が来る可能性が上がる、という実利もあります。

4. 並列度の上限を決める

速く取りたいので並列にする、というのは自然な発想ですが、上限を決めずに並列化すると相手のサーバを叩き潰します。無料で公開してくれている配信元に対してこれをやると、次に困るのは自分です。遮断されれば取得そのものができなくなります。

が明記されている場合はそれに従います。書いていない場合は、まず直列で試して、必要になってから上げるほうが安全です。「何並列まで大丈夫か」は相手にしか分からないので、こちらが遠慮する側に倒すのが基本になります。

5. 生のまま保存する場所を決める

取得したデータを、その場で加工して保存したくなります。要らない列を落とし、日付を変換し、必要な形にしてから書き出す。ところが後になって「落とした列が要る」「変換の仕方を間違えていた」と分かったとき、取り直しになります。相手が過去分を配信していなければ、取り直せません。

受け取ったものをそのまま置く場所と、加工したものを置く場所を分けてください。保存形式は生のままでよく、なら のままで構いません。分析用に整えたものは などに変換して別に置きます。

取得した日付でフォルダを分け、応答をそのまま残す
Python
import jsonfrom datetime import datefrom pathlib import Path
RAW = Path("data/raw")
def save_raw(source: str, name: str, payload) -> Path:    """受け取ったものを加工せずに残す。加工は別の層でやる。"""    d = RAW / source / date.today().isoformat()    d.mkdir(parents=True, exist_ok=True)    path = d / f"{name}.json"    path.write_text(json.dumps(payload, ensure_ascii=False), encoding="utf-8")    return path
保存の判断は「取り直せるか」で決める

相手が過去分をいつでも配信しているなら、生データを残す価値は下がります。逆に最新の状態しか返さないAPI(在庫、順位、板情報など)は、その時点の値を残さないと二度と手に入りません。

この5つを決めた状態から始める

タイムアウト、やり直す失敗の範囲、名乗り、並列度、生データの置き場所。どれも実装としては数行ですが、決めずに書き始めると後から入れ直すのが高くつく種類のものです。次回は、この中でも取りこぼしが起きやすいを扱います。

取得したデータをどう検証し、どう保存するかについては 壊れないデータ基盤の作り方 でも扱っています。この連載は、その手前の「取ってくる」部分だけを細かく見ていきます。

シェア

この記事の感想を教えてください

あなたの 1 クリックで、本当にこの記事は更新されます。「もっと詳しく」「続編希望」が一定数集まった記事は、 ふくふくが 実際に内容を拡充したり続編記事を公開 します。 送信したリアクションはお使いのブラウザに記録され、再カウントされません。

シリーズの外も探す:

まずは、現状を聞かせてください。

要件が固まっていなくて大丈夫です。現状診断と方針提案までを無料でお手伝いします。

無料相談フォームへ hello [at] hukuhuku [dot] co [dot] jp