1

I am trying to use connexion/Flask to return a base64-encoded image generated by PIL/pillow in a HTTP Response.

Having upgraded to python3.7 from python2.7, that part of the code works unaltered.

However, when running inside Docker (python3.7-slim), I get the time-honoured TypeError: Object of type bytes is not JSON serializable (full Traceback below).

The encoding is undertaken via

cutout_b64 = base64.b64encode(sbuffer.getvalue()).decode("ascii")

PLEASE NOTE: There are many many many answers that suggest applying .decode(...) but this does not work inside Docker! The question is:

Q. Why does this work outside Docker but not inside the container? How do I fix this? Is it a LANG difference perhaps?

Thanks as ever

Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1950, in full_dispatch_request
    rv = self.dispatch_request()
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1936, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/usr/local/lib/python3.7/site-packages/connexion/decorators/decorator.py", line 68, in wrapper
    response = function(request)
  File "/usr/local/lib/python3.7/site-packages/connexion/decorators/uri_parsing.py", line 149, in wrapper
    response = function(request)
  File "/app/custom_validators.py", line 107, in wrapper
    response = function(request)
  File "/usr/local/lib/python3.7/site-packages/connexion/decorators/response.py", line 110, in wrapper
    return _wrapper(request, response)
  File "/usr/local/lib/python3.7/site-packages/connexion/decorators/response.py", line 90, in _wrapper
    self.operation.api.get_connexion_response(response, self.mimetype)
  File "/usr/local/lib/python3.7/site-packages/connexion/apis/abstract.py", line 365, in get_connexion_response
    response = cls._response_from_handler(response, mimetype)
  File "/usr/local/lib/python3.7/site-packages/connexion/apis/abstract.py", line 345, in _response_from_handler
    return cls._build_response(mimetype=mimetype, data=response, extra_context=extra_context)
  File "/usr/local/lib/python3.7/site-packages/connexion/apis/flask_api.py", line 186, in _build_response
    data, status_code, serialized_mimetype = cls._prepare_body_and_status_code(data=data, mimetype=mimetype, status_code=status_code, extra_context=extra_context)
  File "/usr/local/lib/python3.7/site-packages/connexion/apis/abstract.py", line 417, in _prepare_body_and_status_code
    body, mimetype = cls._serialize_data(data, mimetype)
  File "/usr/local/lib/python3.7/site-packages/connexion/apis/flask_api.py", line 203, in _serialize_data
    body = cls.jsonifier.dumps(data)
  File "/usr/local/lib/python3.7/site-packages/connexion/jsonifier.py", line 57, in dumps
    return self.json.dumps(data, **kwargs) + '\n'
  File "/usr/local/lib/python3.7/site-packages/flask/json/__init__.py", line 211, in dumps
    rv = _json.dumps(obj, **kwargs)
  File "/usr/local/lib/python3.7/json/__init__.py", line 238, in dumps
    **kw).encode(obj)
  File "/usr/local/lib/python3.7/json/encoder.py", line 201, in encode
    chunks = list(chunks)
  File "/usr/local/lib/python3.7/json/encoder.py", line 431, in _iterencode
    yield from _iterencode_dict(o, _current_indent_level)
  File "/usr/local/lib/python3.7/json/encoder.py", line 405, in _iterencode_dict
    yield from chunks
  File "/usr/local/lib/python3.7/json/encoder.py", line 405, in _iterencode_dict
    yield from chunks
  File "/usr/local/lib/python3.7/json/encoder.py", line 405, in _iterencode_dict
    yield from chunks
  File "/usr/local/lib/python3.7/json/encoder.py", line 438, in _iterencode
    o = _default(o)
  File "/usr/local/lib/python3.7/site-packages/connexion/apps/flask_app.py", line 146, in default
    return json.JSONEncoder.default(self, o)
  File "/usr/local/lib/python3.7/site-packages/flask/json/__init__.py", line 100, in default
    return _json.JSONEncoder.default(self, o)
  File "/usr/local/lib/python3.7/json/encoder.py", line 179, in default
    raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type bytes is not JSON serializable
jtlz2
  • 7,700
  • 9
  • 64
  • 114
  • 1
    Best starting point imho would be to ensure that both output's (or inputs reasoning from the python instance) are actually equal. Is the version inside the container actually getting a bytes object instead of what you expect? Are there additional libraries installed on your host system that aren't available inside the container? Do you run the exact same version of python to begin with? You should be able to exec a shell on the container that maybe allows you to debug inside the container. – JustLudo Oct 28 '21 at 10:52
  • @JustLudo This has been a complete red herring. The issue was that pyzbar returning bytes vs string on the two platforms. I did fix it with a .decode(), but in a different place. The python libs were different. Thank you for your hints and tips - I will close the question down probably. In fact there were two issues - the one masking the other. – jtlz2 Oct 28 '21 at 13:29
  • I’m voting to close this question because I wrote it and the answer turned out to be completely unrelated to how I posed the question. – jtlz2 Oct 28 '21 at 13:30
  • 1
    Good to hear and glad you found the solution though! – JustLudo Oct 28 '21 at 13:55

0 Answers0