You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

requests.post与直接curl请求的差异排查求助

Troubleshooting Battle.net OAuth2 Token Request 400 Error in Python Requests

Let’s dig into why your Python requests call is throwing a 400 internal server error while curl works for the Battle.net OAuth2 token request—this is a common gotcha with strict API endpoints, and we can break down the likely culprits:

1. Explicitly Set the Content-Type Header

Battle.net’s OAuth2 endpoint is picky about request headers, especially Content-Type. Curl automatically sets the correct header when using --data, but requests can sometimes have edge-case behavior if you don’t specify it explicitly. Try forcing the header to match curl’s default:

import requests

token_url = "https://oauth.battle.net/token"
payload = {
    "grant_type": "authorization_code",  # or your specific grant type
    "code": "YOUR_AUTHORIZATION_CODE",
    "client_id": "YOUR_CLIENT_ID",
    "client_secret": "YOUR_CLIENT_SECRET",
    "redirect_uri": "YOUR_REDIRECT_URI"
}
headers = {"Content-Type": "application/x-www-form-urlencoded"}

response = requests.post(token_url, data=payload, headers=headers)
print(f"Status Code: {response.status_code}\nResponse: {response.text}")

2. Verify Payload Encoding Matches Curl

While requests should handle URL encoding automatically, sometimes special characters in values (like your redirect URI) can be encoded differently than curl. Try manually encoding the payload to mirror curl’s behavior:

from urllib.parse import urlencode
import requests

encoded_payload = urlencode(payload)
response = requests.post(token_url, data=encoded_payload, headers=headers)

3. Compare Raw Request Details to Curl

The best way to spot discrepancies is to see exactly what requests is sending vs. curl. Enable debug logging in requests to print full request/response details:

import logging
import http.client
import requests

# Enable debug logging
http.client.HTTPConnection.debuglevel = 1
logging.basicConfig()
logging.getLogger().setLevel(logging.DEBUG)
requests_log = logging.getLogger("requests.packages.urllib3")
requests_log.setLevel(logging.DEBUG)
requests_log.propagate = True

# Run your request as normal
response = requests.post(token_url, data=payload, headers=headers)

Then run your curl command with the -v flag to get its verbose output. Compare every line:

  • Check if requests is adding extra headers (like a default User-Agent—try setting it to match curl’s, e.g., headers["User-Agent"] = "curl/7.88.1" with your curl version)
  • Look for differences in header casing (unlikely, but possible with strict endpoints)
  • Confirm the payload is identical in both requests

4. Disable Automatic Redirects

requests follows redirects by default, while curl doesn’t unless you use -L. Sometimes a 400 error can be masked by a redirect. Try disabling redirects to see the raw error response:

response = requests.post(token_url, data=payload, headers=headers, allow_redirects=False)

5. Rule Out Proxy/SSL Environment Differences

If you’re behind a proxy, requests might be using it differently than curl. Try disabling proxies for the request:

response = requests.post(token_url, data=payload, headers=headers, proxies={"http": None, "https": None})

Also, verify your Python environment has up-to-date SSL certificates—outdated certs can cause silent failures that manifest as 400 errors.

6. Use a Persistent Session

Sometimes using a requests.Session() ensures consistent header handling across requests, which can fix subtle issues:

session = requests.Session()
session.headers.update(headers)
response = session.post(token_url, data=payload)

内容的提问来源于stack exchange,提问作者giuliocatte

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 07:49:50