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

解决USDA ESMIS API的Bad Request错误——Python requests调用问题

Fixing 400 Bad Request When Calling USDA ESMIS API with Python Requests

Let's break down why your curl command works but your Python code doesn't, and fix it step by step.

The Root Cause

When you use curl with -d '{"auth": {...}}' and set Content-Type: application/json, you're sending a raw JSON string as the request body. But in your original Python code, passing a dictionary to the data parameter tells Requests to encode it as application/x-www-form-urlencoded (form data) instead of JSON—even if you manually set the Content-Type header. The USDA API expects JSON, so it rejects the mismatched form data with a 400 error.

The Fix: Use the json Parameter

Requests has a built-in json parameter that handles both serializing your dictionary to JSON and setting the correct Content-Type: application/json header automatically. Here's the corrected code:

import requests
import getpass

email = "r******@gmail.com"
password = getpass.getpass()

data = {"auth": {"email": email, "password": password}}
url = "https://usda.library.cornell.edu/user_token"

# Use the json parameter instead of data
response = requests.post(url, json=data)

print(f"Status Code: {response.status_code}")
# Check the actual error message from the server (critical for debugging!)
if response.status_code != 200:
    print("Server Error Message:", response.text)
else:
    print("Success! Token:", response.json())

If You Still Run Into Issues

If you tried the json parameter and it didn't work, here are quick troubleshooting checks:

  • Verify credentials: Temporarily print the data dictionary (don't commit this to code!) to make sure the email and password from getpass are correctly captured.
  • Check for special characters: If your password has characters like &, =, or quotes, json ensures they're properly escaped in the request—something form encoding might mangle.
  • Avoid conflicting headers: When using json, you don't need to manually set Content-Type—Requests does it for you. If you add the header anyway, double-check for typos (e.g., application/json is spelled correctly).

Alternative: Manual JSON Serialization

If you prefer to use data (not recommended, but for completeness), you need to manually serialize the dictionary to a JSON string with json.dumps:

import json
import requests
import getpass

email = "r******@gmail.com"
password = getpass.getpass()

data = {"auth": {"email": email, "password": password}}
headers = {"Content-Type": "application/json"}
url = "https://usda.library.cornell.edu/user_token"

response = requests.post(url, data=json.dumps(data), headers=headers)

Always check response.text when you get a 400 error—it will usually tell you exactly what the server is missing or rejecting (e.g., "invalid JSON format" or "missing auth fields").

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:29:52