关于 API GET 调用中的身份验证问题
Question about authentication in API GET call
我正在尝试使用美国农业部网站上描述的食品数据中心 REST API 访问基本食品信息:
对于这个项目,我使用 R 中的 httr (v 1.3.1) 包进行调用。
API 调用的文档看起来不错,并提供了一些示例;不幸的是,这些示例中的 none 使用了 R,并且由于我对 API 开发知之甚少,所以我不确定文档的 "content" 应该如何翻译给我。该文档提供了以下示例:
curl -H "Content-Type:application/json"
-d '{"generalSearchInput":"Cheddar cheese"}'
-X POST
https://DEMO_KEY@api.nal.usda.gov/fdc/v1/search
我看到一个 "Content-Type" header 和一个 body,其中字符串 "Cheddar cheese" 被提供给一个名为 generalSearchInput[=40 的参数=].看来我需要用我自己的 API 键替换 'DEMO_KEY' 字符串。
我宁愿不分享我自己的 API 密钥,而是 it's painless to request one(单击 link,输入 name/email,稍后获得密钥,甚至没有以确认电子邮件)。
下面是我在 httr 包中复制此调用的尝试:
httr::POST(url = "https://api.nal.usda.gov/fdc/v1/search",
authenticate(user = "<MyAPIKey>", password = "", type = "basic"),
query = list(generalSearchInput = "Cheddar cheese",
encode = "json")
)
响应如下:
Response [https://api.nal.usda.gov/fdc/v1/search]
Date: 2019-10-10 20:34
Status: 403
Content-Type: application/json
Size: 141 B
{
"error": {
"code": "API_KEY_INVALID",
"message": "An invalid api_key was supplied. Get one at https://api.nal.usda.gov:443"
}
这也许并不奇怪。我遇到了一些问题:
如何正确地将我的 API 键传递给调用?我尝试使用基本的 HTTP 身份验证 as described on the api.data.gov website documentation(即密钥作为用户名和空密码)来这样做,但我认为我这样做不正确。
根据 documentation,您可以通过这种方式在 POST 请求的正文中包含 JSON 数据:
httr::POST(
url = "https://api.nal.usda.gov/fdc/v1/search",
authenticate(user = "<MyAPIKey>", password = "", type = "basic"),
body = list(generalSearchInput = "Cheddar cheese"),
encode = "json"
)
不确定您是否仍在处理此问题,但我从 Github 上的某个人那里找到的这段代码可能会有所帮助。它一直在为我工作。您只需要填写 apiKey 和一个特定的 foodID。
导入请求
进口 json
import pandas as pd #if 你想将响应添加到数据框以使其更易于使用(该代码未在此处显示)
api键=''
foodID = ''
def nutrient_API(apiKey, foodID):
#calls 获取 api 和 json 加载
api_resp = json.loads(requests.get('https://api.nal.usda.gov/fdc/v1/' + foodID + '?api_key=' + apiKey).text)
#只有return营养信息
api_nutrients = api_resp['foodNutrients']
#first entry 是它的描述、foodID 和数据库条目类型
nutrientDict = {"FoodID": [api_resp['description'],foodID, api_resp['dataType']]}
for items in api_nutrients:
if 'amount' in items:
#each entry includes nutrient name, nutrient id, amount, and its respective unit
nutrientDict.update({(items['nutrient']['name']): [(items['nutrient']['id']),
(items['amount']),(items['nutrient']['unitName'])]})
#print(nutrientDict)
return(nutrientDict)
我正在尝试使用美国农业部网站上描述的食品数据中心 REST API 访问基本食品信息:
对于这个项目,我使用 R 中的 httr (v 1.3.1) 包进行调用。
API 调用的文档看起来不错,并提供了一些示例;不幸的是,这些示例中的 none 使用了 R,并且由于我对 API 开发知之甚少,所以我不确定文档的 "content" 应该如何翻译给我。该文档提供了以下示例:
curl -H "Content-Type:application/json"
-d '{"generalSearchInput":"Cheddar cheese"}'
-X POST
https://DEMO_KEY@api.nal.usda.gov/fdc/v1/search
我看到一个 "Content-Type" header 和一个 body,其中字符串 "Cheddar cheese" 被提供给一个名为 generalSearchInput[=40 的参数=].看来我需要用我自己的 API 键替换 'DEMO_KEY' 字符串。
我宁愿不分享我自己的 API 密钥,而是 it's painless to request one(单击 link,输入 name/email,稍后获得密钥,甚至没有以确认电子邮件)。
下面是我在 httr 包中复制此调用的尝试:
httr::POST(url = "https://api.nal.usda.gov/fdc/v1/search",
authenticate(user = "<MyAPIKey>", password = "", type = "basic"),
query = list(generalSearchInput = "Cheddar cheese",
encode = "json")
)
响应如下:
Response [https://api.nal.usda.gov/fdc/v1/search]
Date: 2019-10-10 20:34
Status: 403
Content-Type: application/json
Size: 141 B
{
"error": {
"code": "API_KEY_INVALID",
"message": "An invalid api_key was supplied. Get one at https://api.nal.usda.gov:443"
}
这也许并不奇怪。我遇到了一些问题:
如何正确地将我的 API 键传递给调用?我尝试使用基本的 HTTP 身份验证 as described on the api.data.gov website documentation(即密钥作为用户名和空密码)来这样做,但我认为我这样做不正确。
根据 documentation,您可以通过这种方式在 POST 请求的正文中包含 JSON 数据:
httr::POST(
url = "https://api.nal.usda.gov/fdc/v1/search",
authenticate(user = "<MyAPIKey>", password = "", type = "basic"),
body = list(generalSearchInput = "Cheddar cheese"),
encode = "json"
)
不确定您是否仍在处理此问题,但我从 Github 上的某个人那里找到的这段代码可能会有所帮助。它一直在为我工作。您只需要填写 apiKey 和一个特定的 foodID。
导入请求 进口 json import pandas as pd #if 你想将响应添加到数据框以使其更易于使用(该代码未在此处显示)
api键=''
foodID = ''
def nutrient_API(apiKey, foodID): #calls 获取 api 和 json 加载 api_resp = json.loads(requests.get('https://api.nal.usda.gov/fdc/v1/' + foodID + '?api_key=' + apiKey).text) #只有return营养信息 api_nutrients = api_resp['foodNutrients'] #first entry 是它的描述、foodID 和数据库条目类型 nutrientDict = {"FoodID": [api_resp['description'],foodID, api_resp['dataType']]}
for items in api_nutrients:
if 'amount' in items:
#each entry includes nutrient name, nutrient id, amount, and its respective unit
nutrientDict.update({(items['nutrient']['name']): [(items['nutrient']['id']),
(items['amount']),(items['nutrient']['unitName'])]})
#print(nutrientDict)
return(nutrientDict)