简体   繁体   中英

How to return a json file line by line in flask?

I am writing a api to download json file. Suppose I have 3 dict:

{"task_name":"task1","task_info":"aaaaa"}
{"task_name":"task2","task_info":"bbbbb"}
{"task_name":"task3","task_info":"ccccc"}

I want to return these dict into one json file.Here is what I did:

data = json.dumps(tasks_info, default=str)
response = make_response(data, 200, {'mimetype': 'application/json'})
response.headers['Content-Disposition'] = "attachment;filename={}.json".format(urllib.parse.quote('result'))
return response

tasks_info is a list that contains 3 dict. The result file open like that:

[{"task_name":"task1","task_info":"aaaaa"},{"task_name":"task2","task_info":"bbbbb"},{"task_name":"task3","task_info":"ccccc"}]

It is a very long line. What I want to get looks like

[   // the '[' and ']' is not necessary
{"task_name":"task1","task_info":"aaaaa"},
{"task_name":"task2","task_info":"bbbbb"},
{"task_name":"task3","task_info":"ccccc"}
]

I want every dict show in a distinct line instead of every dict shown in same line. Are there any way to change the result file look like?

The relevant command that formats this output takes place in json.dumps(). There are a bunch of commands you can give to format your json. A conventional approach is to define the indent level:

import json

tasks_info = [{"task_name":"task1","task_info":"aaaaa"},{"task_name":"task2","task_info":"bbbbb"},{"task_name":"task3","task_info":"ccccc"}]
data = json.dumps(tasks_info, indent=2)
print(data)

Which pretty-prints the json into:

[
  {
    "task_info": "aaaaa", 
    "task_name": "task1"
  }, 
  {
    "task_info": "bbbbb", 
    "task_name": "task2"
  }, 
  {
    "task_info": "ccccc", 
    "task_name": "task3"
  }
]

To achieve the exact formatting you desire, you need to define your own formatter class. I used this answer and edited it to fit your formatting requirements. Here is the full code:

import _ctypes
import json
import re

class OneDictPerLine(object):
    def __init__(self, value):
        self.value = value
    def __repr__(self):
        if not isinstance(self.value, list):
            return repr(self.value)
        else:  # Sort the representation of any dicts in the list.
            reps = ('{{{}}}'.format(', '.join(
                        ('{!r}: {!r}'.format(k, v) for k, v in sorted(v.items()))
                    )) if isinstance(v, dict)
                        else
                    repr(v) for v in self.value)
            return '[ \n' + ',\n'.join(reps) + '\n ]'


def di(obj_id):
    """ Reverse of id() function. """
    # from https://stackoverflow.com/a/15012814/355230
    return _ctypes.PyObj_FromPtr(obj_id)


class MyEncoder(json.JSONEncoder):
    FORMAT_SPEC = "@@{}@@"
    regex = re.compile(FORMAT_SPEC.format(r"(\d+)"))

    def default(self, obj):
        return (self.FORMAT_SPEC.format(id(obj)) if isinstance(obj, OneDictPerLine)
                else super(MyEncoder, self).default(obj))

    def encode(self, obj):
        format_spec = self.FORMAT_SPEC  # Local var to expedite access.
        json_repr = super(MyEncoder, self).encode(obj)  # Default JSON repr.

        # Replace any marked-up object ids in the JSON repr with the value
        # returned from the repr() of the corresponding Python object.
        for match in self.regex.finditer(json_repr):
            id = int(match.group(1))
            # Replace marked-up id with actual Python object repr().
            json_repr = json_repr.replace(
                       '"{}"'.format(format_spec.format(id)), repr(di(id)))

        return json_repr


tasks_info = [{"task_name":"task1","task_info":"aaaaa"},{"task_name":"task2","task_info":"bbbbb"},{"task_name":"task3","task_info":"ccccc"}]
data = json.dumps(OneDictPerLine(tasks_info), cls=MyEncoder)
print(data)
#make response and return data ...

output:

[ 
{'task_info': 'aaaaa', 'task_name': 'task1'},
{'task_info': 'bbbbb', 'task_name': 'task2'},
{'task_info': 'ccccc', 'task_name': 'task3'}
]

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