Как вернуть json файл построчно в flask? - PullRequest
0 голосов
/ 09 мая 2020

Я пишу api для загрузки json файла. Предположим, у меня есть 3 dict:

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

Я хочу вернуть эти dict в один json файл. Вот что я сделал:

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 - это список, содержащий 3 диктат Файл результатов открывается так:

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

Это очень длинная строка. То, что я хочу получить, выглядит так:

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

Я хочу, чтобы каждый dict отображался в отдельной строке, а не каждый dict, отображаемый в той же строке. Есть ли способ изменить внешний вид файла результатов?

1 Ответ

0 голосов
/ 09 мая 2020

Соответствующая команда, форматирующая этот вывод, находится в json .dumps (). Существует множество команд, которые можно использовать для форматирования файла json. Обычный подход состоит в том, чтобы определить уровень отступа:

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)

Что красиво печатает json в:

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

Чтобы добиться желаемого точного форматирования, вам необходимо определить ваш собственный класс форматтера. Я использовал этот ответ и отредактировал его в соответствии с вашими требованиями к форматированию. Вот полный код:

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 ...

вывод:

[ 
{'task_info': 'aaaaa', 'task_name': 'task1'},
{'task_info': 'bbbbb', 'task_name': 'task2'},
{'task_info': 'ccccc', 'task_name': 'task3'}
]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...