简体   繁体   中英

flask application: trying to jsonify a dictionary

Background Info

I'm trying to write my first flask / python REST API. So far, I have a GET that connects to a redis database and tries to convert a dictionary to json... and then return those results.

Problem

When I try to call jsonify on my dict object, it fails with the following error:

Traceback (most recent call last):
  File "/usr/lib/python3.6/site-packages/flask/app.py", line 1982, in wsgi_app
    response = self.full_dispatch_request()
  File "/usr/lib/python3.6/site-packages/flask/app.py", line 1614, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/usr/lib/python3.6/site-packages/flask/app.py", line 1517, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/lib/python3.6/site-packages/flask/_compat.py", line 33, in reraise
    raise value
  File "/usr/lib/python3.6/site-packages/flask/app.py", line 1612, in full_dispatch_request
    rv = self.dispatch_request()
  File "/usr/lib/python3.6/site-packages/flask/app.py", line 1598, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/var/www/localhost/htdocs/widgets/widgets.py", line 51, in get_profile
    return jsonify(res_dict)
  File "/usr/lib/python3.6/site-packages/flask/json.py", line 263, in jsonify
    (dumps(data, indent=indent, separators=separators), '\n'),
  File "/usr/lib/python3.6/site-packages/flask/json.py", line 123, in dumps
    rv = _json.dumps(obj, **kwargs)
  File "/usr/lib/python3.6/json/__init__.py", line 238, in dumps
    **kw).encode(obj)
  File "/usr/lib/python3.6/json/encoder.py", line 201, in encode
    chunks = list(chunks)
  File "/usr/lib/python3.6/json/encoder.py", line 430, in _iterencode
    yield from _iterencode_dict(o, _current_indent_level)
  File "/usr/lib/python3.6/json/encoder.py", line 376, in _iterencode_dict
    raise TypeError("key " + repr(key) + " is not a string")
TypeError: key b'email1' is not a string

The code looks like this:

 20 def get_db_profile(mailbox):
 21     """ connects to redis and queries for profile """
 22     try:
 23         my_redis = redis.Redis(connection_pool=POOL)
 24         response = my_redis.hgetall(55555)
 25         logging.info(response.keys())
 26         logging.info(response.items())
 27         #response = '123455555'
 28         return response
 29     except Exception as ex:
 30         return "Error:", ex

47 @application.route("/widgets/api/<int:mailbox>", methods=['GET'])
48 def get_profile(mailbox):
49     res_dict = get_db_profile(mailbox)
50 #    return application.response_class(jsonify(res_dict), content_type='application/json')
51     return jsonify(res_dict)
52 #    return '12345'
53

I added some logging as you can see on line 25 to see what the keys() look like. this is what I see in the log file:

lab-1:/var/www/localhost/htdocs/widgets# cat /tmp/widgets.log
root - INFO - dict_keys([b'email1', b'email2'])

REDIS Data

This is how I created the redis data:

127.0.0.1:6379[5]> hmset 55555 email1 johndoe@hotmail.com email2 jd@yahoo.com
OK
127.0.0.1:6379[5]>

Questions

Should i be able to convert from dict object to json string? What is the 'b' in the log files?

lab-1:/var/www/localhost/htdocs/widgets# cat /tmp/widgets.log
root - INFO - dict_keys([b'email1', b'email2'])
root - INFO - dict_items([(b'email1', b'johndoe@hotmail.com'), (b'email2', b'jd@yahoo.com')])

How do I send back a proper JSON response?

EDIT 1

I found this question/answer: How to parse python b' string containing dict and based on that I tried to change my logic to look like this:

47 @application.route("/pvmailprofiles/api/<int:mailbox>", methods=['GET'])
48 def get_profile(mailbox):
49     res_dict = get_db_profile(mailbox)
50 #    return application.response_class(jsonify(res_dict), content_type='application/json')
51     #return jsonify(res_dict)
52     return res_dict[b'email1']
53 #    return '12345'
54

Line 52 - you can see that as a test I've hardcoded the 'b' and then the key name. And it works - it returns the specific email address. But I need to find a way to "just" convert everything to json and return to callee.

Have you tried first importing json like so

import json

and then doing

json.dumps(myDict)

and then to load it again if needed.

json.loads(response.text)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM