6

Возврат JSON-ответа из представления Flask

9

У меня есть функция, которая анализирует CSV-файл с помощью библиотеки Pandas и возвращает словарь с краткой информацией. Я хочу вернуть результаты в ответе из представления Flask. Как правильно вернуть ответ в формате JSON?

Пример кода:

@app.route("/summary")
def summary():
    d = make_summary()
    # вернуть результат в формате JSON

Какой подход следует использовать для отправки данных в формате JSON из функции представления?

5 ответ(ов)

2

jsonify сериализует данные, которые вы передаете ему, в формат JSON. Если вы хотите сериализовать данные самостоятельно, выполните аналогичные действия, которые делает jsonify, создав ответ с status=200 и mimetype='application/json'.

Вот пример кода:

from flask import json

@app.route('/summary')
def summary():
    data = make_summary()  # Ваши данные для сериализации
    response = app.response_class(
        response=json.dumps(data),  # Сериализация данных в JSON
        status=200,                  # Статус ответа
        mimetype='application/json'  # MIME тип
    )
    return response

В этом примере make_summary() генерирует данные, которые вы хотите вернуть, а json.dumps(data) преобразует их в строку JSON. Затем вы создаете экземпляр response_class, передавая сериализованные данные, статус и MIME-тип.

0

Если по каким-то причинам вы не хотите использовать jsonify, вы можете сделать то, что он делает, вручную. Вызовите flask.json.dumps, чтобы создать данные в формате JSON, затем верните ответ с заголовком контента application/json.

from flask import json

@app.route('/summary')
def summary():
    data = make_summary()
    response = app.response_class(
        response=json.dumps(data),
        mimetype='application/json'
    )
    return response

Обратите внимание, что flask.json отличается от встроенного модуля json. Он будет использовать более быстрый модуль simplejson, если он доступен, и позволяет интегрировать различные функции с вашим приложением Flask.

0

В Flask версии 1.1.x поддерживается возможность возвращать JSON-словарь без необходимости вызова jsonify. Однако, если вы хотите вернуть что-то, отличное от словаря, вам все равно нужно использовать jsonify.

Вот пример:

@app.route("/")
def index():
    return {
        "api_stuff": "values",
    }

Этот код эквивалентен следующему:

@app.route("/")
def index():
    return jsonify({
        "api_stuff": "values",
    })

Если вам интересно узнать больше, можете ознакомиться с запросом на добавление этой функции: https://github.com/pallets/flask/pull/3111.

0

В вашем коде используется декоратор return_json, который оборачивает результаты функции и преобразует их в формат JSON с помощью jsonify. Это действительно делает код более читабельным, особенно когда у вас несколько условных ветвей возврата.

Однако стоит отметить, что ваш декоратор не поддерживает возвращение кортежа, например, в формате (content, status). В вашем случае, если вам нужно возвращать ошибки с соответствующими статусами, вы решили использовать app.errorhandler, что является допустимым подходом.

Вот как это работает:

  1. Декоратор return_json принимает функцию f, оборачивает её и вызывает, передавая все ключевые аргументы (kwargs).
  2. Результат выполнения функции f передается в jsonify, что всегда будет возвращать JSON ответ.

Вы можете улучшить обработку различных типов возврата, если будет нужна такая функциональность. Например, если необходимо возвращать не только данные, но и статус, можно комбинировать логику внутри декоратора.

Вот пример, как это можно сделать:

import functools
from flask import jsonify

def return_json(f):
    @functools.wraps(f)
    def inner(*args, **kwargs):
        result = f(*args, **kwargs)
        if isinstance(result, tuple):
            return jsonify(result[0]), result[1]
        return jsonify(result)
    return inner

@app.route('/test/<arg>')
@return_json
def test(arg):
    if arg == 'list':
        return [1, 2, 3], 200
    elif arg == 'dict':
        return {'a': 1, 'b': 2}, 200
    elif arg == 'bool':
        return True, 200
    return 'none of them', 404

Теперь ваш декоратор поддерживает возврат кортежей, что позволяет указывать как содержимое ответа, так и HTTP статус. Это может быть удобнее при обработки ошибок и различных статусов ответа.

0

В версиях Flask до 0.11 функция jsonify не позволяла возвращать массив напрямую. Вместо этого вам необходимо передать список в качестве аргумента с именем.

Правильный пример будет выглядеть следующим образом:

@app.route('/get_records')
def get_records():
    results = [
        {
          "rec_create_date": "12 Jun 2016",
          "rec_dietary_info": "nothing",
          "rec_dob": "01 Apr 1988",
          "rec_first_name": "New",
          "rec_last_name": "Guy",
        },
        {
          "rec_create_date": "1 Apr 2016",
          "rec_dietary_info": "Nut allergy",
          "rec_dob": "01 Feb 1988",
          "rec_first_name": "Old",
          "rec_last_name": "Guy",
        },
    ]
    return jsonify(results=results)

Обратите внимание, что вместо list нужно использовать переменную results, содержащую ваши данные.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь