1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

request.post(json=)で沼った話

Posted at

はじめに

どうも。@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仕様書はよく読もうな:hugging:
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?