Проблема с 500 Error

Нужно решить проблему со входом на 127.0.0.1:5000/status. На интенсиве я постарался написать json для сервера, но получаю Internal Server Error при переходе по вышеуказанной ссылке. Что поменять в коде можно?

from flask import Flask
import datetime
import json


app = Flask(__name__)

status = {
    "time": datetime.datetime.now(),
    "name": "PARROTHI",
    "status": True
}

@app.route("/")
def hello():
    return "Welcome for all!"


@app.route("/status")
def status():
    return json.dumps(status)

app.run()

Ответы (2 шт):

Автор решения: gil9red

У вас имя функции совпадает с именем переменной, поэтому в json.dumps попадала ссылка на функцию. Попробуйте переименовать переменную, например в status_data

И у flask для возврата JSON есть функцию jsonify

from flask import Flask, jsonify

status_data = {
...

@app.route("/status")
def status():
    return jsonify(status_data)

Покажу разницу между return json.dumps(status_data) и return jsonify(status_data):

...
status_data = {
    # NOTE: по умолчанию json.dumps не умеет работать, в отличии от jsonify, с типом datetime.datetime,
    #       поэтому поместил вместо него его строковое представление
    "time": str(datetime.datetime.now()),
    "name": "PARROTHI",
    "status": True
}

@app.route("/status1")
def status1():
    return jsonify(status_data)

@app.route("/status2")
def status2():
    return json.dumps(status_data)
...

return jsonify(status_data)

Как видно, от сервера пришел заголовок Content-Type-application/json из-за этого клиент понимает, что это JSON (и браузер Firefox для этого типа подсунул удобный редактор):

введите сюда описание изображения


return json.dumps(status_data)

Возвращая просто строку из метода, сервер передал Content-Type=text/html; charset=utf-8, т.е. для клиента это просто текст HTML

введите сюда описание изображения


UPD.

Добавил полный пример:

from flask import Flask, jsonify
import datetime
import json


app = Flask(__name__)

status_data = {
    # NOTE: по умолчанию json.dumps не умеет работать, в отличии от jsonify, с типом datetime.datetime,
    #       поэтому поместил вместо него его строковое представление
    "time": str(datetime.datetime.now()),
    "name": "PARROTHI",
    "status": True
}

@app.route("/")
def hello():
    return """
    Welcome for all!
    <br>
    <a href="/status1">/status1</>
    <br>
    <a href="/status2">/status2</>
    """

@app.route("/status1")
def status1():
    return jsonify(status_data)

@app.route("/status2")
def status2():
    return json.dumps(status_data)

if __name__ == '__main__':
    app.debug = True
    app.run()
→ Ссылка
Автор решения: Xander

В добавок к тому, что написано в соседнем ответе, объекты типа datetime.datetime не являются JSON-сериализуемыми, поэтому вы не можете сделать json.dumps для такого объекта. Для этого его нужно привести либо к строке, либо к timestamp.

Например так:

status = {
    "time": str(datetime.datetime.now()),  # вот так вот
    "name": "PARROTHI",
    "status": True
}

Кстати, с этим местом связана ещё одна проблема - так как у вас status определён за пределами функции, в глобальной области видимости, datetime.now() будет расчитываться один раз - в момент запуска программы.

Чтобы время бралось актуальное, нужно либо внести status в функцию, которая его использует, либо завернуть в отдельную функцию, которая будет вызываться там, где это значение понадобится.

→ Ссылка