はじめに
どうも。@Kai-Rosyです。
日頃、pythonでRestfulAPIの開発なんかをやってるんですが、今回、業務で単純なAPIリクエストに詰まったので記事にしました。
問題
requests.post()で json= を使用すると、デフォルトで空白を含む形式のJSONが生成されます。
しかし、API仕様によっては 空白なしのコンパクトなJSONを要求されることがあります。
この場合、json= をそのまま使うと200レスポンスを得られない可能性があります。というか200レスポンスになりません。
(今回、対向システムへのAPIリクエストで401が返却されて詰まりました。。。)
import requests
payload = {"request_id": "0001", "amount": 1000}
response = requests.post(
url="https://example.com/api",
json=payload
)
print(response.request.body)
出力を見ると、:の間と,の後にスペースが入っていることが確認できます。
# response.request.bodyの出力結果
b'{"request_id": "0001", "amount": 1000}'
解決方法
json= の代わりに data= を使用する。
import requests
import json
payload = {"request_id": "0001", "amount": 1000}
# 空白を含まない形式のjsonをdump
compact_payload = json.dumps(payload, separators=(",", ":"))
# POSTリクエストの実行
response = requests.post(
url="https://example.com/api",
headers={"Content-Type": "application/json"},
data=compact_payload
)
print(response.request.body)
separators=(",", ":") を使用することで、空白文字を含まないjsonを生成できます。
# response.request.bodyの出力結果
b'{"request_id":"0001","amount":1000}'
json= を使用する場合は、requests が自動的に Content-Type: application/jsonヘッダーを追加してくれるようですが、data=を使用する際は、手動で以下のヘッダー設定が必要です。
(手動追加も忘れていてさらに詰まりました。。。)
"Content-Type": "application/json"
おわりに
- API仕様書はよく読もうな