题意:使用 Python requests 调用 OpenAI API 时缺少 model 参数。
问题背景:
I'm trying to call OpenAI API from Python. I know they have their own openai
package, but I want to use a generic solution. I chose the requests
package for its flexibility. Here is my call
我正在尝试从 Python 调用 OpenAI API。我知道他们有自己的 openai
包,但我想使用一个通用的解决方案。我选择了 requests
包,因为它更灵活。下面是我的调用代码。
>>> headers = {"Authorization": "Bearer xxx"}
>>> url = 'https://api.openai.com/v1/completions'
>>> data = {'model': 'text-davinci-002', 'prompt': 'Once upon a time'}
>>> requests.get(url, headers=headers, data=data).content
... "error": {\n "message": "you must provide a model parameter"
The header contains the API token. It's correct, I tried it. I also tried to pass the same dictionary as json, as data but as a json string. Always the same error message. Any idea how to make the call?
请求头中包含了 API 令牌,是正确的,我已经测试过。我还尝试将相同的字典作为 JSON 或字符串传递,总是出现相同的错误信息。有什么办法可以让调用成功吗?
Update:
>>> requests.get(url, headers=headers, json=data).content
>>> requests.get(url, headers=headers, json=json.dumps(data)).content
>>> requests.get(url, headers=headers, data=json.dumps(data)).content
>>> requests.get(url, headers=headers, data=json.dumps(data).encode()).content
These all return the same error. I tried to add 'Content-Type': 'application/json'
to the headers too.
这些方法都会返回相同的错误。我也尝试在请求头中添加 'Content-Type': 'application/json'
。
update2: It works for the completion endpoint with POST
, but not for the edit endpoint.
更新2:对于 completion 端点使用 POST 方法是可行的,但对 edit 端点无效。
>>> completion_url = "https://api.openai.com/v1/completions"
>>> completion_data = {'model': 'text-davinci-002', 'prompt': 'Once upon a time'}
>>> requests.post(completion_url, headers=headers, json=completion_data).json()
... # it works
>>> edit_url = "https://api.openai.com/v1/edits"
>>> completion_data = {'model': 'text-davinci-002', 'input': 'Once upon a time', 'instruction': 'Continue'}
>>> requests.get(edit_url, headers=headers, json=edit_data).json()['error']['message']
'you must provide a model parameter'
>>> requests.post(edit_url, headers=headers, json=edit_data).json()['error']['message']
'Invalid URL (POST /v1/edits)'
问题解决:
The API expects a JSON request body,not a form-encoded request. And, you need to use the requests.post()
method to send the right HTTP method.
翻译为:
“API 期望接收的是 JSON 格式的请求体,而不是表单编码的请求。另外,你需要使用 `requests.post()` 方法来发送正确的 HTTP 请求。”
Use the json
argument, not the data
argument, and the right method:
使用 json
参数,而不是 data
参数,并确保使用正确的方法:
requests.post(url, headers=headers, json=data)
See the Create completion section of the OpenAI documentation, where the curl
source code sample posts JSON:
请参阅 OpenAI 文档的创建 completion 部分,其中的 curl 示例代码是通过 POST 方法发送 JSON 的:
curl https://api.openai.com/v1/completions \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-d '{
"model": "text-davinci-002",
"prompt": "Say this is a test",
"max_tokens": 6,
"temperature": 0
}'
as well as the More complicated POST requests section of the documentation:
以及文档中的更复杂的 POST 请求部分:
Typically, you want to send some form-encoded data — much like an HTML form. To do this, simply pass a dictionary to the
data
argument. Your dictionary of data will automatically be form-encoded when the request is made[.][...]
There are times that you may want to send data that is not form-encoded.
[...].
If you need [the
application/json
header] set and you don’t want to encode thedict
yourself, you can also pass it directly using thejson
parameter (added in version 2.4.2) and it will be encoded automatically[.]
(Bold emphasis mine, slightly edited for clarity).
Demo:
>>> import requests
>>> key = "<APIKEY>"
>>> headers = {"Authorization": f"Bearer {key}"}
>>> data = {'model': 'text-davinci-002', 'prompt': 'Once upon a time'}
>>> requests.post(url, headers=headers, json=data).json()
{'id': 'cmpl-6HIPWd1eDo6veh3FkTRsv9aJyezBv', 'object': 'text_completion', 'created': 1669580366, 'model': 'text-davinci-002', 'choices': [{'text': ' there was a castle up in space. In this castle there was a queen who', 'index': 0, 'logprobs': None, 'finish_reason': 'length'}], 'usage': {'prompt_tokens': 4, 'completion_tokens': 16, 'total_tokens': 20}}
The openai Python library uses the requests library under the hood but takes care of details like how to send HTTP requests correctly for you.
openai
Python 库在底层使用了 requests 库,但它会为你处理如何正确发送 HTTP 请求等细节。