Raise TypeError(f"Object of type {type(o).__name__} is not JSON serializable") error in flask

Question:
Hello, I am trying to make a multiuser pixel art system similar to r/place on Reddit, however, when it restarts I get this error raise TypeError(f"Object of type {type(o).__name__} is not JSON serializable").
It even appears randomly at times even when the server does not restart, and it always appeared before I used Dict.
It appears to always be when a pixel is added to the database also.
I tried using return jsonify(dict(json.loads(pixels))) on the part where the client can fetch the pixels, but it gives a new error raise TypeError(f'the JSON object must be str, bytes or bytearray, '.
Can anyone help me?
Repl link:
https://replit.com/@StudioHawaii/Pixel-Board?v=1
Server code:

import os
from flask import Flask, render_template, request, jsonify
from flask_socketio import SocketIO, emit
from replit import db
import json

app = Flask(__name__)
socketio = SocketIO(app)
app.config["TEMPLATES_AUTO_RELOAD"] = (
    True  # if true, it auto reloads templates if a change is made to them
)
app.secret_key = os.environ["SECRET_KEY"]  # The secret key
board_size = 80  # The size of the pixel board (Warning: A very large size may either break the app or overload repl db)
colors = [
    "orange",
    "purple",
    "white",
    "cyan",
    "blue",
    "brown",
]  # Avalible colors for the user to use (first color is defualt)
try:
    pixels = db["pixels"]  # The list of pixels from the database
except:  # Set the pixels key if the key was not found
    db["pixels"] = {}
    pixels = db["pixels"]
pixels["board_size"] = board_size  # sets the board size for the info for pixels
"""Routes"""


@app.route("/")
def index():
    """The index page (Board is on it)"""
    if request.headers["X-Replit-User-Name"]:
        return render_template("index.html", size=board_size, colors=colors)
    else:
        return render_template("login.html")


@app.route("/pixels")
def pixel_data():
    """Used for the client to get pixel data"""
    return jsonify(dict(pixels))


"""Socketio events"""


@socketio.on("change_pixel")
def change_pixel(pixel):
    """The event when a client sends a request to change one of the pixels"""
    if (
        not pixel.get("Pixel")
        or not pixel.get("Color")
        or not pixel.get("Pixel").startswith("pixel_")
        or not request.headers["X-Replit-User-Name"]
        or pixel["Color"] not in colors
    ):  # Make sure the data is valid
        return  # Cancels changing the pixel if it does not meet the requirements
    pixel["Owner_name"] = request.headers[
        "X-Replit-User-Name"
    ]  # Adds the username to the pixel data
    pixel["Owner_id"] = request.headers[
        "X-Replit-User-Id"
    ]  # Adds the userid to the pixel data
    pixels[pixel["Pixel"]] = pixel  # Upload the pixel to the database
    emit("pixel_change", pixel, broadcast=True)


socketio.run(app, host="0.0.0.0")

I can’t seem to reproduce this with the repl you sent. Are you still experiencing this problem? If you are, could you provide exact instructions on how to reproduce it, thanks.

Whenever you try to convert an object that is not natively serializable to JSON you get this error. The best thing for you is to debbug your code to check the pixels, you know, make sure that every data you put into the dictionary is serializable.

For example, in your @app.route

@app.route("/pixels")
def pixel_data():
    """Used for the client to get pixel data"""
    try:
        data_to_return = dict(pixels)
        if isinstance(data_to_return, dict):
            return jsonify(data_to_return)
        else:
            # If pixels is not a dict you can return an error message
            return jsonify({"error": "Data is not in the expected format"})
    except Exception as e:
        return jsonify({"error": str(e)})
1 Like

Can you explain what you mean by reproducing it?

I got the error Object of type ObservedDict is not JSON serializable, is there a way to convert it from an ObservedDict?
If not, do you know whats causing it to be that way?

do this:

import json

json.loads(db.get_raw("key"))
1 Like

Thank you to everyone who tried to help me, this is my new code:

For booting up the database:

try:
  pixels = json.loads(db.get_raw("pixels"))
except Exception as e: #Set the pixels key if the key was not found
  print(e)
  db['pixels'] = {}
  pixels = json.loads(db.get_raw("pixels"))

Handle uploading a pixel:

@socketio.on('change_pixel')
def change_pixel(pixel):
  """The event when a client sends a request to change one of the pixels"""
  if not pixel.get("Pixel") or not pixel.get('Color') or not pixel.get("Pixel").startswith("pixel_") or not request.headers['X-Replit-User-Name'] or pixel['Color'] not in colors: #Make sure the data is valid
    return #Cancels changing the pixel if it does not meet the requirements
  pixel["Owner_name"] = request.headers['X-Replit-User-Name'] #Adds the username to the pixel data
  pixel["Owner_id"] = request.headers['X-Replit-User-Id'] #Adds the userid to the pixel data
  pixels[pixel["Pixel"]] = pixel #Upload the pixel to the database
  db["pixels"] = pixels
  emit('pixel_change', pixel, broadcast=True)
1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.