Gpt-4-vision-preview return json decode error for custom image

I followed instruction to use custom image

# Path to your image
image_path = "./test_results/bird.jpg"

# Function to encode the image
def encode_image(image_path):
  with open(image_path, "rb") as image_file:
    return base64.b64encode(image_file.read()).decode('utf-8')

# Getting the base64 string
base64_image = encode_image(image_path)

headers = {
  "Content-Type": "application/json",
  "Authorization": f"Bearer {api_key}"
}

payload = {
  "model": "gpt-4-vision-preview",
  "messages": [
    {
      "role": "user",
      "content": [
        {
          "type": "text",
          "text": "What’s in this image?"
        },
        {
          "type": "image_url",
          "image_url": {
            "url": f"data:image/jpeg;base64,{base64_image}"
          }
        }
      ]
    }
  ],
}

response = requests.post("https://api.openai.com/v1/chat/completions", headers=headers, json=payload)

print(response.json())

I got

{
	"name": "JSONDecodeError",
	"message": "Expecting value: line 1 column 1 (char 0)",
	"stack": "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[0;31mJSONDecodeError\u001b[0m                           Traceback (most recent call last)\nFile \u001b[0;32m/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/requests/models.py:971\u001b[0m, in \u001b[0;36mResponse.json\u001b[0;34m(self, **kwargs)\u001b[0m\n\u001b[1;32m    970\u001b[0m \u001b[39mtry\u001b[39;00m:\n\u001b[0;32m--> 971\u001b[0m     \u001b[39mreturn\u001b[39;00m complexjson\u001b[39m.\u001b[39;49mloads(\u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49mtext, \u001b[39m*\u001b[39;49m\u001b[39m*\u001b[39;49mkwargs)\n\u001b[1;32m    972\u001b[0m \u001b[39mexcept\u001b[39;00m JSONDecodeError \u001b[39mas\u001b[39;00m e:\n\u001b[1;32m    973\u001b[0m     \u001b[39m# Catch JSON-related errors and raise as requests.JSONDecodeError\u001b[39;00m\n\u001b[1;32m    974\u001b[0m     \u001b[39m# This aliases json.JSONDecodeError and simplejson.JSONDecodeError\u001b[39;00m\n\nFile \u001b[0;32m/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/json/__init__.py:346\u001b[0m, in \u001b[0;36mloads\u001b[0;34m(s, cls, object_hook, parse_float, parse_int, parse_constant, object_pairs_hook, **kw)\u001b[0m\n\u001b[1;32m    343\u001b[0m \u001b[39mif\u001b[39;00m (\u001b[39mcls\u001b[39m \u001b[39mis\u001b[39;00m \u001b[39mNone\u001b[39;00m \u001b[39mand\u001b[39;00m object_hook \u001b[39mis\u001b[39;00m \u001b[39mNone\u001b[39;00m \u001b[39mand\u001b[39;00m\n\u001b[1;32m    344\u001b[0m         parse_int \u001b[39mis\u001b[39;00m \u001b[39mNone\u001b[39;00m \u001b[39mand\u001b[39;00m parse_float \u001b[39mis\u001b[39;00m \u001b[39mNone\u001b[39;00m \u001b[39mand\u001b[39;00m\n\u001b[1;32m    345\u001b[0m         parse_constant \u001b[39mis\u001b[39;00m \u001b[39mNone\u001b[39;00m \u001b[39mand\u001b[39;00m object_pairs_hook \u001b[39mis\u001b[39;00m \u001b[39mNone\u001b[39;00m \u001b[39mand\u001b[39;00m \u001b[39mnot\u001b[39;00m kw):\n\u001b[0;32m--> 346\u001b[0m     \u001b[39mreturn\u001b[39;00m _default_decoder\u001b[39m.\u001b[39;49mdecode(s)\n\u001b[1;32m    347\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39mcls\u001b[39m \u001b[39mis\u001b[39;00m \u001b[39mNone\u001b[39;00m:\n\nFile \u001b[0;32m/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/json/decoder.py:337\u001b[0m, in \u001b[0;36mJSONDecoder.decode\u001b[0;34m(self, s, _w)\u001b[0m\n\u001b[1;32m    333\u001b[0m \u001b[39m\u001b[39m\u001b[39m\"\"\"Return the Python representation of ``s`` (a ``str`` instance\u001b[39;00m\n\u001b[1;32m    334\u001b[0m \u001b[39mcontaining a JSON document).\u001b[39;00m\n\u001b[1;32m    335\u001b[0m \n\u001b[1;32m    336\u001b[0m \u001b[39m\"\"\"\u001b[39;00m\n\u001b[0;32m--> 337\u001b[0m obj, end \u001b[39m=\u001b[39m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49mraw_decode(s, idx\u001b[39m=\u001b[39;49m_w(s, \u001b[39m0\u001b[39;49m)\u001b[39m.\u001b[39;49mend())\n\u001b[1;32m    338\u001b[0m end \u001b[39m=\u001b[39m _w(s, end)\u001b[39m.\u001b[39mend()\n\nFile \u001b[0;32m/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/json/decoder.py:355\u001b[0m, in \u001b[0;36mJSONDecoder.raw_decode\u001b[0;34m(self, s, idx)\u001b[0m\n\u001b[1;32m    354\u001b[0m \u001b[39mexcept\u001b[39;00m \u001b[39mStopIteration\u001b[39;00m \u001b[39mas\u001b[39;00m err:\n\u001b[0;32m--> 355\u001b[0m     \u001b[39mraise\u001b[39;00m JSONDecodeError(\u001b[39m\"\u001b[39m\u001b[39mExpecting value\u001b[39m\u001b[39m\"\u001b[39m, s, err\u001b[39m.\u001b[39mvalue) \u001b[39mfrom\u001b[39;00m \u001b[39mNone\u001b[39;00m\n\u001b[1;32m    356\u001b[0m \u001b[39mreturn\u001b[39;00m obj, end\n\n\u001b[0;31mJSONDecodeError\u001b[0m: Expecting value: line 1 column 1 (char 0)\n\nDuring handling of the above exception, another exception occurred:\n\n\u001b[0;31mJSONDecodeError\u001b[0m                           Traceback (most recent call last)\n\u001b[1;32m/Users/weiji/MyCode/Python/ui-checkout/test_openai.ipynb Cell 5\u001b[0m line \u001b[0;36m4\n\u001b[1;32m     <a href='vscode-notebook-cell:/Users/weiji/MyCode/Python/ui-checkout/test_openai.ipynb#W2sZmlsZQ%3D%3D?line=16'>17</a>\u001b[0m payload \u001b[39m=\u001b[39m {\n\u001b[1;32m     <a href='vscode-notebook-cell:/Users/weiji/MyCode/Python/ui-checkout/test_openai.ipynb#W2sZmlsZQ%3D%3D?line=17'>18</a>\u001b[0m   \u001b[39m\"\u001b[39m\u001b[39mmodel\u001b[39m\u001b[39m\"\u001b[39m: \u001b[39m\"\u001b[39m\u001b[39mgpt-4-vision-preview\u001b[39m\u001b[39m\"\u001b[39m,\n\u001b[1;32m     <a href='vscode-notebook-cell:/Users/weiji/MyCode/Python/ui-checkout/test_openai.ipynb#W2sZmlsZQ%3D%3D?line=18'>19</a>\u001b[0m   \u001b[39m\"\u001b[39m\u001b[39mmessages\u001b[39m\u001b[39m\"\u001b[39m: [\n\u001b[0;32m   (...)\u001b[0m\n\u001b[1;32m     <a href='vscode-notebook-cell:/Users/weiji/MyCode/Python/ui-checkout/test_openai.ipynb#W2sZmlsZQ%3D%3D?line=34'>35</a>\u001b[0m   ],\n\u001b[1;32m     <a href='vscode-notebook-cell:/Users/weiji/MyCode/Python/ui-checkout/test_openai.ipynb#W2sZmlsZQ%3D%3D?line=35'>36</a>\u001b[0m }\n\u001b[1;32m     <a href='vscode-notebook-cell:/Users/weiji/MyCode/Python/ui-checkout/test_openai.ipynb#W2sZmlsZQ%3D%3D?line=37'>38</a>\u001b[0m response \u001b[39m=\u001b[39m requests\u001b[39m.\u001b[39mpost(\u001b[39m\"\u001b[39m\u001b[39mhttps://api.openai.com/v1/chat/completions\u001b[39m\u001b[39m\"\u001b[39m, headers\u001b[39m=\u001b[39mheaders, json\u001b[39m=\u001b[39mpayload)\n\u001b[0;32m---> <a href='vscode-notebook-cell:/Users/weiji/MyCode/Python/ui-checkout/test_openai.ipynb#W2sZmlsZQ%3D%3D?line=39'>40</a>\u001b[0m \u001b[39mprint\u001b[39m(response\u001b[39m.\u001b[39;49mjson())\n\nFile \u001b[0;32m/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/requests/models.py:975\u001b[0m, in \u001b[0;36mResponse.json\u001b[0;34m(self, **kwargs)\u001b[0m\n\u001b[1;32m    971\u001b[0m     \u001b[39mreturn\u001b[39;00m complexjson\u001b[39m.\u001b[39mloads(\u001b[39mself\u001b[39m\u001b[39m.\u001b[39mtext, \u001b[39m*\u001b[39m\u001b[39m*\u001b[39mkwargs)\n\u001b[1;32m    972\u001b[0m \u001b[39mexcept\u001b[39;00m JSONDecodeError \u001b[39mas\u001b[39;00m e:\n\u001b[1;32m    973\u001b[0m     \u001b[39m# Catch JSON-related errors and raise as requests.JSONDecodeError\u001b[39;00m\n\u001b[1;32m    974\u001b[0m     \u001b[39m# This aliases json.JSONDecodeError and simplejson.JSONDecodeError\u001b[39;00m\n\u001b[0;32m--> 975\u001b[0m     \u001b[39mraise\u001b[39;00m RequestsJSONDecodeError(e\u001b[39m.\u001b[39mmsg, e\u001b[39m.\u001b[39mdoc, e\u001b[39m.\u001b[39mpos)\n\n\u001b[0;31mJSONDecodeError\u001b[0m: Expecting value: line 1 column 1 (char 0)"
}

Here’s your error without all the ANSI terminal code garbage:

JSONDecodeError: Expecting value: line 1 column 1 (char 0)


Traceback (most recent call last):
File “/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/requests/models.py”, line 971, in Response.json(self, **kwargs)
try:
return complexjson.loads(self.text, **kwargs)
except JSONDecodeError as e:
# Catch JSON-related errors and raise as requests.JSONDecodeError
# This aliases json.JSONDecodeError and simplejson.JSONDecodeError

File “/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/json/init.py”, line 346, in loads(s, cls, object_hook, parse_float, parse_int, parse_constant, object_pairs_hook, **kw)
if (cls is None and object_hook is None and
parse_int is None and parse_float is None and
parse_constant is None and object_pairs_hook is None and not kw):
return _default_decoder.decode(s)

File “/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/json/decoder.py”, line 337, in JSONDecoder.decode(self, s, _w)
“”"
Return the Python representation of s (a str instance
containing a JSON document).
“”"
obj, end = self.raw_decode(s, idx=_w(s, 0).end())

File “/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/json/decoder.py”, line 355, in JSONDecoder.raw_decode(self, s, idx)
except StopIteration as err:
raise JSONDecodeError(“Expecting value”, s, err.value) from None
return obj, end

JSONDecodeError: Expecting value: line 1 column 1 (char 0)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File “/Users/weiji/MyCode/Python/ui-checkout/test_openai.ipynb”, Cell 5, line 4
payload = {
“model”: “gpt-4-vision-preview”,
“messages”: [

],
}
response = requests.post(“https://api.openai.com/v1/chat/completions”, headers=headers, json=payload)
print(response.json())

File “/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/requests/models.py”, line 975, in Response.json(self, **kwargs)
except JSONDecodeError as e:
# Catch JSON-related errors and raise as requests.JSONDecodeError
# This aliases json.JSONDecodeError and simplejson.JSONDecodeError
raise RequestsJSONDecodeError(e.msg, e.doc, e.pos)

JSONDecodeError: Expecting value: line 1 column 1 (char 0)

The last line of your code was expecting some json text as a response - but got nothing. We need to put in some error check so you can see reported errors.

Let’s finish this up:

  • if an http or API error, print the error,
  • import statements,
  • fill in a real fake API key where you need your own funded key from OpenAI,
  • set the resize resolution to low so you aren’t paying many tokens for testing,
  • add max_tokens so you get the whole answer without it being cut off.
import base64
import requests

# Path to your image
image_path = "./bird.jpg"

# Function to encode the image
def encode_image(image_path):
  with open(image_path, "rb") as image_file:
    return base64.b64encode(image_file.read()).decode('utf-8')

# Getting the base64 string
base64_image = encode_image(image_path)

headers = {
  "Content-Type": "application/json",
  "Authorization": f"Bearer sk-123412341234123412341234"
}

payload = {
  "model": "gpt-4-vision-preview",
  "max_tokens": 500,
  "messages": [
    {
      "role": "user",
      "content": [
        {
          "type": "text",
          "text": "What’s in this image?"
        },
        {
          "type": "image_url",
          "image_url": {
            "url": f"data:image/jpeg;base64,{base64_image}",
            "detail": "low"
            
          }
        }
      ]
    }
  ],
}

response = requests.post("https://api.openai.com/v1/chat/completions", headers=headers, json=payload)

if response.status_code != 200:
    print(f"HTTP error {response.status_code}: {response.text}")
else:
    print(response.json())

Then if you do something wrong, like not provide a correct API key, you get the error that the API produced:

HTTP error 401: {
“error”: {
“message”: “Incorrect API key provided: sk-12341234xxxxx. You can find your API key at https://platform.openai.com/account/api-keys.”,
“type”: “invalid_request_error”,
“param”: null,
“code”: “invalid_api_key”
}
}

Do it right and you get your answer, a dictionary which you can further parse:

{‘id’: ‘chatcmpl-39869280293052325’, ‘object’: ‘chat.completion’, ‘created’: 1702004999, ‘model’: ‘gpt-4-1106-vision-preview’, ‘usage’: {‘prompt_tokens’: 98, ‘completion_tokens’: 104, ‘total_tokens’: 202}, ‘choices’: [{‘message’: {‘role’: ‘assistant’, ‘content’: “The image shows a colorful bird perched on a branch. It appears to be a kingfisher, identifiable by its distinctive beak shape and vibrant plumage. The bird has a combination of bright blue feathers on its back and wings, with orange to reddish hues on its underside and face, along with a white throat. The beak is long, straight, and pointed, characteristic of kingfishers, which are known for their fishing abilities. The dark background helps to accentuate the bird’s striking colors.”}, ‘finish_details’: {‘type’: ‘stop’, ‘stop’: ‘<|fim_suffix|>’}, ‘index’: 0}]}

Easier is the openai python library, examples of use which you can find in the API Reference sidebar under “chat”.