Felix Wallis
Felix Wallis

Reputation: 33

How to fix 'TypeError: Object of type bytes is not JSON serializable'

I am using Microsoft Azures Vision API to recognised handwritten text from a local JPEG image. I am editing Microsofts source code to allow images to be recognised from a local source rather than from a URL. However, I am unsure what to do about this error: 'TypeError: Object of type bytes is not JSON serializable'.

image_path = "/Users/FelixWallis/Downloads/IMG_2430.jpg"

image_data = open(image_path, "rb").read()
headers = {'Ocp-Apim-Subscription-Key': subscription_key}

params  = {'mode': 'Handwritten'}
response = requests.post(
    text_recognition_url, headers=headers, params=params, json=image_data)
response.raise_for_status()


operation_url = response.headers["Operation-Location"]

analysis = {}
poll = True
while (poll):
    response_final = requests.get(
        response.headers["Operation-Location"], headers=headers)
    analysis = response_final.json()
    time.sleep(1)
    if ("recognitionResult" in analysis):
        poll= False 
    if ("status" in analysis and analysis['status'] == 'Failed'):
        poll= False

polygons=[]
if ("recognitionResult" in analysis):
    # Extract the recognized text, with bounding boxes.
    polygons = [(line["boundingBox"], line["text"])
        for line in analysis["recognitionResult"]["lines"]]

plt.figure(figsize=(15, 15))
image = Image.open(BytesIO(image_data))
ax = plt.imshow(image)
for polygon in polygons:
    vertices = [(polygon[0][i], polygon[0][i+1])
        for i in range(0, len(polygon[0]), 2)]
    text     = polygon[1]
    patch    = Polygon(vertices, closed=True, fill=False, linewidth=2, color='y')
    ax.axes.add_patch(patch)
    plt.text(vertices[0][0], vertices[0][1], text, fontsize=20, va="top")
_ = plt.axis("off")

Traceback:

TypeError                                 Traceback (most recent call last)
<ipython-input-2-9eba870c3121> in <module>
     32 params  = {'mode': 'Handwritten'}
     33 response = requests.post(
---> 34     text_recognition_url, headers=headers, params=params, json=image_data)
     35 response.raise_for_status()
     36 

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/requests/api.py in post(url, data, json, **kwargs)
    114     """
    115 
--> 116     return request('post', url, data=data, json=json, **kwargs)
    117 
    118 

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/requests/api.py in request(method, url, **kwargs)
     58     # cases, and look like a memory leak in others.
     59     with sessions.Session() as session:
---> 60         return session.request(method=method, url=url, **kwargs)
     61 
     62 

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/requests/sessions.py in request(self, method, url, params, data, headers, cookies, files, auth, timeout, allow_redirects, proxies, hooks, stream, verify, cert, json)
    517             hooks=hooks,
    518         )
--> 519         prep = self.prepare_request(req)
    520 
    521         proxies = proxies or {}

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/requests/sessions.py in prepare_request(self, request)
    460             auth=merge_setting(auth, self.auth),
    461             cookies=merged_cookies,
--> 462             hooks=merge_hooks(request.hooks, self.hooks),
    463         )
    464         return p

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/requests/models.py in prepare(self, method, url, headers, files, data, params, auth, cookies, hooks, json)
    314         self.prepare_headers(headers)
    315         self.prepare_cookies(cookies)
--> 316         self.prepare_body(data, files, json)
    317         self.prepare_auth(auth, url)
    318 

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/requests/models.py in prepare_body(self, data, files, json)
    464             # provides this natively, but Python 3 gives a Unicode string.
    465             content_type = 'application/json'
--> 466             body = complexjson.dumps(json)
    467             if not isinstance(body, bytes):
    468                 body = body.encode('utf-8')

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/__init__.py in dumps(obj, skipkeys, ensure_ascii, check_circular, allow_nan, cls, indent, separators, default, sort_keys, **kw)
    229         cls is None and indent is None and separators is None and
    230         default is None and not sort_keys and not kw):
--> 231         return _default_encoder.encode(obj)
    232     if cls is None:
    233         cls = JSONEncoder

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/encoder.py in encode(self, o)
    197         # exceptions aren't as detailed.  The list call should be roughly
    198         # equivalent to the PySequence_Fast that ''.join() would do.
--> 199         chunks = self.iterencode(o, _one_shot=True)
    200         if not isinstance(chunks, (list, tuple)):
    201             chunks = list(chunks)

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/encoder.py in iterencode(self, o, _one_shot)
    255                 self.key_separator, self.item_separator, self.sort_keys,
    256                 self.skipkeys, _one_shot)
--> 257         return _iterencode(o, 0)
    258 
    259 def _make_iterencode(markers, _default, _encoder, _indent, _floatstr,

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/encoder.py in default(self, o)
    177 
    178         """
--> 179         raise TypeError(f'Object of type {o.__class__.__name__} '
    180                         f'is not JSON serializable')
    181 

TypeError: Object of type bytes is not JSON serializable

Upvotes: 2

Views: 10262

Answers (1)

Peter Pan
Peter Pan

Reputation: 24138

According to your codes and error information, the issue was caused by passing the image_data value of local image to the incorrect parameter json(it should be data) and missing the Content-Type header for local image in the method requests.post, please refer to the reference of Recognize Text API carefully.

enter image description here

Here is my code as reference.

import requests

image_path = '<the file path, like /Users/FelixWallis/Downloads/IMG_2430.jpg>'
image_data = open(image_path, "rb").read()

headers = {
    'Ocp-Apim-Subscription-Key': '<your subscription key>',
    'Content-Type': 'application/octet-stream'
}

params  = {'mode': 'Handwritten'}
text_recognition_url = 'https://<your cognitive service region, such as southeastasia for me>.api.cognitive.microsoft.com/vision/v2.0/recognizeText'
response = requests.post(text_recognition_url, headers=headers, params=params, data=image_data)

print(response.raw.status) # the result is 202
print(response.raise_for_status()) # the result is None

operation_url = response.headers["Operation-Location"]
print(operation_url) # the result for me is like https://southeastasia.api.cognitive.microsoft.com/vision/v2.0/textOperations/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

Upvotes: 6

Related Questions